Title: C Programming: Program Design Including Data Structures, Fifth Edition
1C ProgrammingProgram Design IncludingData
Structures, Fifth Edition
- Chapter 18 Stacks and Queues
2Objectives
- In this chapter, you will
- Learn about stacks
- Examine various stack operations
- Learn how to implement a stack as an array
- Learn how to implement a stack as a linked list
- Discover stack applications
- Learn how to use a stack to remove recursion
3Objectives (cont'd.)
- Learn about queues
- Examine various queue operations
- Learn how to implement a queue as an array
- Learn how to implement a queue as a linked list
- Discover queue applications
4Stacks
- Stack list of homogenous elements
- Addition and deletion occur only at one end,
called the top of the stack - Example in a cafeteria, the second tray can be
removed only if first tray has been removed - Last in first out (LIFO) data structure
- Operations
- Push to add an element onto the stack
- Pop to remove an element from the stack
5Stacks (contd.)
6Stacks (contd.)
7Stack Operations
- In the abstract class stackADT
- initializeStack
- isEmptyStack
- isFullStack
- push
- top
- pop
8Implementation of Stacks as Arrays
- First element can go in first array position, the
second in the second position, etc. - The top of the stack is the index of the last
element added to the stack - Stack elements are stored in an array
- Stack element is accessed only through top
- To keep track of the top position, use a variable
called stackTop
9Implementation of Stacks as Arrays (cont'd.)
- Because stack is homogeneous
- You can use an array to implement a stack
- Can dynamically allocate array
- Enables user to specify size of the array
- The class stackType implements the functions of
the abstract class stackADT
10Implementation of Stacks as Arrays (cont'd.)
11Implementation of Stacks as Arrays (cont'd.)
- C arrays begin with the index 0
- Must distinguish between
- The value of stackTop
- The array position indicated by stackTop
- If stackTop is 0, the stack is empty
- If stackTop is nonzero, the stack is not empty
- The top element is given by stackTop - 1
12Implementation of Stacks as Arrays (cont'd.)
13Initialize Stack
14Empty Stack
- If stackTop is 0, the stack is empty
15Full Stack
- The stack is full if stackTop is equal to
maxStackSize
16Push
- Store the newItem in the array component
indicated by stackTop - Increment stackTop
- Must avoid an overflow
17Push (cont'd.)
18Return the Top Element
19Pop
- Simply decrement stackTop by 1
- Must check for underflow condition
20Pop (contd.)
21Pop (contd.)
22Copy Stack
23Constructor and Destructor
24Constructor and Destructor (cont'd.)
25Copy Constructor
26Overloading the Assignment Operator ()
27Stack Header File
- Place definitions of class and functions (stack
operations) together in a file
28Programming Example Highest GPA
- Input program reads an input file with each
students GPA and name - 3.5 Bill
- 3.6 John
- 2.7 Lisa
- 3.9 Kathy
- 3.4 Jason
- 3.9 David
- 3.4 Jack
- Output the highest GPA and all the names
associated with the highest GPA
29Programming Example Problem Analysis and
Algorithm Design
- Read the first GPA and name of the student
- This is the highest GPA so far
- Read the second GPA and student name
- Compare this GPA with highest GPA so far
- New GPA is greater than highest GPA so far
- Update highest GPA, initialize stack, add to
stack - New GPA is equal to the highest GPA so far
- Add name to stack
- New GPA is smaller than the highest GPA
- Discard
30Programming Example Problem Analysis and
Algorithm Design (contd.)
31Programming Example Problem Analysis and
Algorithm Design (contd.)
32Linked Implementation of Stacks
- Array only allows fixed number of elements
- If number of elements to be pushed exceeds array
size - Program may terminate
- Linked lists can dynamically organize data
- In a linked representation, stackTop is pointer
to top element in stack
33Linked Implementation of Stacks (contd.)
34Default Constructor
- Initializes the stack to an empty state when a
stack object is declared - Sets stackTop to NULL
35Empty Stack and Full Stack
- In the linked implementation of stacks, the
function isFullStack does not apply - Logically, the stack is never full
36Initialize Stack
37Push
- The newElement is added at the beginning of the
linked list pointed to by stackTop
38Push (cont'd.)
39Push (cont'd.)
- We do not need to check whether the stack is full
before we push an element onto the stack
40Return the Top Element
41Pop
- Node pointed to by stackTop is removed
42Pop (cont'd.)
43Pop (cont'd.)
44Copy Stack
45Copy Stack (cont'd.)
- Notice that this function is similar to the
definition of copyList for linked lists
46Constructors and Destructors
47Overloading the Assignment Operator ()
48Stack as Derived from the class
unorderedLinkedList
- Our implementation of push is similar to
insertFirst (discussed for general lists) - Other functions are similar too
- initializeStack and initializeList
- isEmptyList and isEmptyStack
- linkedStackType can be derived from
linkedListType - class linkedListType is abstract
- Must implement pop as described earlier
49Derived Stack (contd.)
- unorderedLinkedListType is derived from
linkedListType - Provides the definitions of the abstract
functions of the class linkedListType - We can derive the linkedStackType from
unorderedLinkedListType
50Application of Stacks Postfix Expressions
Calculator
- Infix notation usual notation for writing
arithmetic expressions - The operator is written between the operands
- Example a b
- The operators have precedence
- Parentheses can be used to override precedence
51Application of Stacks Postfix Expressions
Calculator (cont'd.)
- Prefix (Polish) notation the operators are
written before the operands - Introduced by the Polish mathematician Jan
Lukasiewicz - Early 1920s
- The parentheses can be omitted
- Example a b
52Application of Stacks Postfix Expressions
Calculator (cont'd.)
- Reverse Polish notation the operators follow the
operands (postfix operators) - Proposed by the Australian philosopher and early
computer scientist Charles L. Hamblin - Late 1950's
- Advantage the operators appear in the order
required for computation - Example a b c
- In a postfix expression a b c
53Application of Stacks Postfix Expressions
Calculator (cont'd.)
54Application of Stacks Postfix Expressions
Calculator (cont'd.)
- Postfix notation has important applications in
computer science - Many compilers first translate arithmetic
expressions into postfix notation and then
translate this expression into machine code - Evaluation algorithm
- Scan expression from left to right
- When an operator is found, back up to get the
operands, perform the operation, and continue
55Application of Stacks Postfix Expressions
Calculator (cont'd.)
56Application of Stacks Postfix Expressions
Calculator (cont'd.)
- Symbols can be numbers or anything else
- , -, , and / are operators
- Pop stack twice and evaluate expression
- If stack has less than two elements ? error
- If symbol is , the expression ends
- Pop and print answer from stack
- If stack has more than one element ? error
- If symbol is anything else
- Expression contains an illegal operator
57Application of Stacks Postfix Expressions
Calculator (cont'd.)
- Examples
- 7 6 3 6 -
- is an illegal operator
- 14 2 3
- Does not have enough operands for
- 14 2 3
- Error stack will have two elements when we
encounter equal () sign
58Application of Stacks Postfix Expressions
Calculator (cont'd.)
- We assume that the postfix expressions are in the
following form - 6 3 2
- If symbol scanned is , next input is a number
- If the symbol scanned is not , then it is
- An operator (may be illegal) or
- An equal sign (end of expression)
- We assume expressions contain only , -, , and /
operators
59Main Algorithm
- Pseudocode
- We will write four functions
- evaluateExpression, evaluateOpr, discardExp, and
printResult
60Function evaluateExpression
61Function evaluateOpr
62Function evaluateOpr (contd.)
63Function discardExp
- This function is called whenever an error is
discovered in the expression
64Function printResult
- If the postfix expression contains no errors, the
function printResult prints the result - Otherwise, it outputs an appropriate message
- The result of the expression is in the stack and
the output is sent to a file
65Function printResult (contd.)
66Removing Recursion Nonrecursive Algorithm to
Print a Linked List Backward
- To print the list backward, first we need to get
to the last node of the list - Problem how do we get back to previous node?
- Links go in only one direction
- Solution save a pointer to each of the nodes
with info 5, 10, and 15 - Use a stack (LIFO)
67Removing Recursion Nonrecursive Algorithm to
Print a Linked List Backward (contd.)
68Removing Recursion Nonrecursive Algorithm to
Print a Linked List Backward (contd.)
- Let us now execute the following statements
- Output
- 20 15 10 5
69Queues
- Queue list of homogeneous elements
- Elements are
- Added at one end (the back or rear)
- Deleted from the other end (the front)
- First In First Out (FIFO) data structure
- Middle elements are inaccessible
- Example
- Waiting line in a bank
70Queue Operations
- Some of the queue operations are
- initializeQueue
- isEmptyQueue
- isFullQueue
- front
- back
- addQueue
- deleteQueue
- Abstract class queueADT defines these operations
71Implementation of Queues as Arrays
- You need at least four (member) variables
- An array to store the queue elements
- queueFront and queueRear
- To keep track of first and last elements
- maxQueueSize
- To specify the maximum size of the queue
72Implementation of Queues as Arrays (cont'd.)
- To add an element to the queue
- Advance queueRear to next array position
- Add element to position pointed by queueRear
- Example array size is 100 originally empty
73Implementation of Queues as Arrays (cont'd.)
- To delete an element from the queue
- Retrieve element pointed to by queueFront
- Advance queueFront to next queue element
74Implementation of Queues as Arrays (cont'd.)
- Will this queue design work?
- Suppose A stands for adding an element to the
queue - And D stands for deleting an element from the
queue - Consider the following sequence of operations
- AAADADADADADADADA...
75Implementation of Queues as Arrays (cont'd.)
- The sequence AAADADADADADADADA... would
eventually set queueRear to point to the last
array position - Giving the impression that the queue is full
76Implementation of Queues as Arrays (cont'd.)
- Solution 1
- When the queue overflows to the rear (i.e.,
queueRear points to the last array position) - Check value of queueFront
- If value of queueFront indicates that there is
room in the front of the array, slide all of the
queue elements toward the first array position - Problem too slow for large queues
- Solution 2 assume that the array is circular
77Implementation of Queues as Arrays (cont'd.)
- To advance the index in a (logically) circular
array
78Implementation of Queues as Arrays (cont'd.)
79Implementation of Queues as Arrays (cont'd.)
80Implementation of Queues as Arrays (cont'd.)
81Implementation of Queues as Arrays (cont'd.)
- Problem
- Figures 19-32b and 19-33b have identical values
for queueFront and queueRear - However, the former represents an empty queue,
whereas the latter shows a full queue - Solution?
82Implementation of Queues as Arrays (cont'd.)
- Solution 1 keep a count
- Incremented when a new element is added to the
queue - Decremented when an element is removed
- Initially, set to 0
- Very useful if user (of queue) frequently needs
to know the number of elements in the queue - We will implement this solution
83Implementation of Queues as Arrays (cont'd.)
- Solution 2 let queueFront indicate index of the
array position preceding the first element - queueRear still indicates index of last one
- Queue empty if
- queueFront queueRear
- Slot indicated by queueFront is reserved
- Queue can hold 99 (not 100) elements
- Queue full if the next available space is the
reserved slot indicated by queueFront
84Implementation of Queues as Arrays (cont'd.)
85Empty Queue and Full Queue
86Initialize Queue
87Front
- Returns the first element of the queue
88Back
- Returns the last element of the queue
89addQueue
90deleteQueue
91Constructors and Destructors
92Constructors and Destructors (cont'd.)
- The array to store the queue elements is created
dynamically - When the queue object goes out of scope, the
destructor simply deallocates the memory occupied
by the array
93Linked Implementation of Queues
- Array size is fixed only a finite number of
queue elements can be stored in it - The array implementation of the queue requires
array to be treated in a special way - Together with queueFront and queueRear
- The linked implementation of a queue simplifies
many of the special cases of the array
implementation - In addition, the queue is never full
94Linked Implementation of Queues (cont'd.)
- Elements are added at one end and removed from
the other - We need to know the front of the queue and the
rear of the queue - Two pointers queueFront and queueRear
95Empty and Full Queue
- The queue is empty if queueFront is NULL
- The queue is never full
96Initialize Queue
- Initializes queue to an empty state
- Must remove all the elements, if any
97addQueue
98front and back Operations
99deleteQueue
100Default Constructor
101Queue Derived from the class unorderedLinkedListTy
pe
- The linked implementation of a queue is similar
to the implementation of a linked list created in
a forward manner - addQueue is similar to insertFirst
- initializeQueue is like initializeList
- isEmptyQueue is similar to isEmptyList
- deleteQueue can be implemented as before
- queueFront is the same as first
- queueRear is the same as last
102Queue Derived from the class unordered
LinkedListType (cont'd.)
- We can derive the class to implement the queue
from linkedListType - Abstract class does not implement all the
operations - However, unorderedLinkedListType is derived from
linkedListType - Provides the definitions of the abstract
functions of the linkedListType - Therefore, we can derive linkedQueueType from
unorderedLinkedListType
103Application of Queues Simulation
- Simulation a technique in which one system
models the behavior of another system - Computer simulations using queues as the data
structure are called queuing systems
104Designing a Queuing System
- Server the object that provides the service
- Customer the object receiving the service
- Transaction time service time, or the time it
takes to serve a customer - Model system that consists of a list of servers
and a waiting queue holding the customers to be
served - Customer at front of queue waits for the next
available server
105Designing a Queuing System (cont'd.)
- We need to know
- Number of servers
- Expected arrival time of a customer
- Time between the arrivals of customers
- Number of events affecting the system
- Performance of system depends on
- How many servers are available
- How long it takes to serve a customer
- How often a customer arrives
106Designing a Queuing System (cont'd.)
- If it takes too long to serve a customer and
customers arrive frequently, then more servers
are needed - System can be modeled as a time-driven simulation
- Time-driven simulation the clock is a counter
- The passage of, say, one minute can be
implemented by incrementing the counter by 1 - Simulation is run for a fixed amount of time
107Customer
108Server
109Server List
- A server list is a set of servers
- At a given time, a server is either free or busy
110Waiting Customers Queue
- When a customer arrives, he/she goes to the end
of the queue - When a server becomes available, the customer at
front of queue leaves to conduct the transaction - After each time unit, the waiting time of each
customer in the queue is incremented by 1 - We can use queueType but must add the operation
of incrementing the waiting time
111Waiting Customers Queue (cont'd.)
112Main Program
- Algorithm
- Declare and initialize the variables
- Main loop (see next slide)
- Print results
113Main Program (cont'd.)
114Summary
- Stack items are added/deleted from one end
- Last In First Out (LIFO) data structure
- Operations push, pop, initialize, destroy, check
for empty/full stack - Can be implemented as array or linked list
- Middle elements should not be accessed
- Postfix notation operators are written after the
operands (no parentheses needed)
115Summary (cont'd.)
- Queue items are added at one end and removed
from the other end - First In First Out (FIFO) data structure
- Operations add, remove, initialize, destroy,
check if queue is empty/full - Can be implemented as array or linked list
- Middle elements should not be accessed
- Restricted versions of arrays and linked lists