Stack and Queue
1
Stack
Data structure with Last-In First-Out (LIFO) behavior
In Out
C B A B C
2
Pop
Typical Operations
on Stack Push
isempty: determines if the stack has no elements
isfull: determines if the stack is full in case
of a bounded sized stack
top: returns the top element in the stack
push: inserts an element into the stack
pop: removes the top element from the stack
push is like inserting at the front of the list
pop is like deleting from the front of the list
3
Creating and Initializing a Stack
Declaration
#define MAX_STACK_SIZE 100 Create and Initialize
typedef struct {
int key; /* just an example, can have
any type of fields depending stack Z;
on what is to be stored */
[Link] = -1;
} element;
typedef struct {
element list[MAX_STACK_SIZE];
int top; /* index of the topmost element */
} stack;
4
Operations
int isfull (stack *s)
{
if (s->top >= int isempty (stack *s)
MAX_STACK_SIZE – 1) {
return 1; if (s->top == -1)
return 0; return 1;
return 0;
}
}
5
Operations
element top( stack *s )
{
return s->list[s->top];
} void pop( stack *s )
{
(s->top)--;
void push( stack *s, element e ) }
{
(s->top)++;
s->list[s->top] = e;
}
6
Application: Parenthesis Matching
Given a parenthesized expression, test whether the
expression is properly parenthesized
Examples:
( )( { } [ ( { } { } ( ) ) ] ) is proper
( ){ [ ] is not proper
({)} is not proper
)([ ] is not proper
([])) is not proper
7
Approach:
Whenever a left parenthesis is
encountered, it is pushed in the stack
Whenever a right parenthesis is
encountered, pop from stack and check
if the parentheses match
Works for multiple types of parentheses
( ), { }, [ ]
8
Parenthesis matching
while (not end of string) do
{
a = get_next_token();
if (a is ‘(‘ or ‘{‘ or ‘[‘) push (a);
if (a is ‘)’ or ‘}’ or ‘]’)
{
if (is_stack_empty( ))
{ print (“Not well formed”); exit(); }
x = top();
pop();
if (a and x do not match)
{ print (“Not well formed”); exit(); }
}
}
if (not is_stack_empty( )) print (“Not well formed”); 9
Recursion can be Fibonacci recurrence:
implemented as a stack fib(n) = 1 if n =0 or 1;
= fib(n – 2) + fib(n – 1)
otherwise;
fib (5)
fib (3) fib (4)
fib (1) fib (2) fib (2) fib (3)
fib (0) fib (1) fib (0) fib (1) fib (1) fib (2)
fib (0) fib (1)
10
Fibonacci Recursion Stack
1 0 0
3 2 2 1 1 2 1
5 4 4 4 4 4 4 3 3
0 0 0 1 1 2 3 3 3
1 1 0
3 3 2 2 1 1
4 5 5 6 6 7 8 11
Tower of Hanoi
A B C
12
Tower of Hanoi
A B C
13
Tower of Hanoi
A B C
14
Tower of Hanoi
A B C
15
Towers of Hanoi Function
void towers (int n, char from, char to, char aux)
{
/* Base Condition */
if (n==1) {
printf (“Disk 1 : %c -> %c \n”, from, to) ;
return ;
}
/* Recursive Condition */
towers (n-1, from, aux, to) ;
printf (“Disk %d : %c -> %c\n”, n, from, to) ;
towers (n-1, aux, to, from) ;
}
16
TOH Recursion Stack
1,A,B,C A to B
A to C A to C A to C
2,A,C,B 1,B,C,A 1,B,C,A 1,B,C,A
A to B A to B A to B A to B
3,A,B,C 2,C,B,A 2,C,B,A 2,C,B,A 2,C,B,A
1,B,C,A B to C 1,C,A,B
A to B A to B A to B C to B
2,C,B,A 2,C,B,A 2,C,B,A 2,C,B,A 1,A,B,C
17
Queue
Data structure with First-In First-Out (FIFO) behavior
Out
In
B A
C B A
18
Typical Operations REAR
on Queue Enqueue
isempty: determines if the queue is empty
isfull: determines if the queue is full
in case of a bounded size queue
front: returns the element at front of the queue
enqueue: inserts an element at the rear
dequeue: removes the element in front
Dequeue
FRONT
19
Possible Implementations
Linear Arrays:
Circular Arrays:
(static/dynamicaly allocated)
(static/dynamically allocated)
front rear
front
rear
Linked Lists: Use a linear
Can be implemented by a 1-d
linked list with insert_rear
array using modulus operations
and delete_front operations
20
Circular Queue
[3] [4]
[2] [5]
[1] [6]
[0] [7]
front=0
rear=0
21
Circular Queue
[3] [4] rear = 4
[4]
[3] C D
[2] [5]
[2] [5] B
After insertion
A
[1] [6] of A, B, C, D
[1] [6]
[0] [7] front=0 [0] [7]
front=0
rear=0
22
Circular Queue
[3] [4] rear = 4
[4]
[3] C D
[2] [5]
[2] [5] B
After insertion
A
[1] [6] of A, B, C, D
[1] [6]
[0] [7] front=0 [0] [7]
front=0
rear=0
[3] [4] rear = 4
front=2 C D
[2] [5]
After deletion of
[1] [6] of A, B
[0] [7]
23
front: index of queue-head (always empty – why?)
rear: index of last element, unless rear = front
[3] [4] rear = 3 front=4
[3] [4]
[2] [5]
[2] [5]
[1] [6] [1] [6]
[0] [7] [0] [7]
front=0
rear=0 Queue Empty Queue Full
Queue Empty Condition: front == rear
Queue Full Condition: front == (rear + 1) % MAX_Q_SIZE
24
Creating and Initializing a Circular
Queue
Declaration
#define MAX_Q_SIZE 100 Create and Initialize
typedef struct {
int key; /* just an example, can have
any type of fields depending queue Q;
on what is to be stored */
[Link] = 0;
} element;
typedef struct { [Link] = 0;
element list[MAX_Q_SIZE];
int front, rear;
} queue;
25
Operations
int isfull (queue *q)
{
if (q->front == ((q->rear + 1) %
MAX_Q_SIZE))
return 1;
return 0; int isempty (queue *q)
} {
if (q->front == q->rear)
return 1;
return 0;
}
26
Operations
element front( queue *q )
{
return q->list[(q->front + 1) % MAX_Q_SIZE];
}
void enqueue( queue *q, element e)
{
q->rear = (q->rear + 1)% void dequeue( queue *q )
MAX_Q_SIZE; {
q->list[q->rear] = e; q-> front =
} (q-> front + 1)%
MAX_Q_SIZE;
}
27
Exercises
• Implement the Queue as a linked list.
• Implement a Priority Queue which maintains the
items in an order (ascending/ descending) and
has additional functions like remove_max and
remove_min
• Maintain a Doctor’s appointment list
28