DS Stack Queue
DS Stack Queue
2 2022
Today’s discussion…
*Stack
* Basic principles
* Operation of stack
* Stack using Array
* Stack using Linked List
* Applications of stack
3
Stack
4
Basic Idea
•A stack is an Abstract Data Type (ADT), commonly used in most
programming languages. It is named stack as it behaves like a real-
world stack, for example – a deck of cards or a pile of plates, etc.
5
Stack Representation
create
isempty
isfull
7
STACK: Last-In-First-Out (LIFO)
• void push (stack *s, int element);
/* Insert an element in the stack */
• int pop (stack *s);
/* Remove and return the top element */
• void create (stack *s);
/* Create a new stack */
• int isempty (stack *s);
/* Check if stack is empty */
• int isfull (stack *s);
/* Check if stack is full */
9
Push using Stack
PUSH
top
top
10
Pop using Stack
POP
top
top DEMO
11
DEMO
*DEMO
12
Stack using Linked List
13
Push using Linked List
PUSH OPERATION
top
14
Pop using Linked List
POP OPERATION
top
Linked Lis
t based St
ack
Demo
15
Basic Idea
• In the array implementation, we would:
• Declare an array of fixed size (which determines the maximum size of
the stack).
17
Stack Creation
18
Pushing an element into stack
void push (stack *s, int element) void push (stack **top, int element)
{ {
stack *new;
if (s->top == (MAXSIZE-1))
{ new = (stack *)malloc (sizeof(stack));
printf (“\n Stack overflow”); if (new == NULL)
exit(-1); {
} printf (“\n Stack is full”);
else exit(-1);
}
{
s->top++; new->value = element;
s->st[s->top] = element; new->next = *top;
} *top = new;
} }
21
Checking for Stack Full
22
30
Example: A Stack using an Array
#include <stdio.h>
#define MAXSIZE 100 20
struct lifo 5
{
int st[MAXSIZE]; 10 100
int top;
};
typedef struct lifo stack;
main() {
stack A, B;
create(&A);
create(&B);
push(&A,10);
push(&A,20);
push(&A,30);
push(&B,100);
push(&B,5);
printf (“%d %d”, pop(&A), pop(&B));
push (&A, pop(&B));
if (isempty(&B))
printf (“\n B is empty”);
23
return;
}
Example: A Stack using Linked List
#include <stdio.h>
struct lifo
{
int value;
struct lifo *next;
};
typedef struct lifo stack;
main() {
stack *A, *B;
create(&A);
create(&B);
push(&A,10);
push(&A,20);
push(&A,30);
push(&B,100);
push(&B,5);
printf (“%d %d”, pop(&A), pop(&B));
push (&A, pop(&B));
if (isempty(B))
printf (“\n B is empty”);
return; 24
}
Applications of Stacks
• Direct applications:
• Page-visited history in a Web browser
• Undo sequence in a text editor
• Chain of method calls in the Java Virtual Machine
• Validate XML
• Indirect applications:
• Auxiliary data structure for algorithms
• Component of other data structures
25
*Example of Stack operations
26
* Infix and Postfix
An application of Stack
27
*Infix Notation
*To add A, B, we write A+B
*To multiply A, B, we write A*B
* The operators ('+' and '*') go in between the operands ('A'
and 'B') This is "Infix" notation
28
Operator Priority Associativity
^ High Right to left
*, / Medium Left to right
+, - Low Left to right
*Prefix Notation.
30
* Another alternative is to put the operators after the operands as in
AB+
and
AB*
* This is Postfix notation.
* The terms infix, prefix, and postfix tell us whether the operators go
between, before, or after the operands
*Postfix Notation
31
* Evaluate 2+3*5.
* + First:
(2+3)*5 = 5*5 = 25
* * First:
2+(3*5) = 2+15 = 17
* Infix notation requires Parentheses.
*Parentheses
32
*• + 2 * 3 5 =
* =+2*35
* = + 2 15 = 17
*• * + 2 3 5 =
* =*+235
* = * 5 5 = 25
* • No parentheses needed!!
*Postfix Notation •
34
Infix and Postfix Notations
• Infix: operators placed between operands:
A+B*C
• Postfix: operands appear before their operators:-
ABC*+
• There are no precedence rules to learn in postfix notation, and
parentheses are never needed
35
Infix to Postfix
Infix Postfix
A+B AB+
A+B*C ABC*+
(A + B) * C AB+C*
A+B*C+D ABC*+D+
(A + B) * (C + D) AB+CD+*
A*B+C*D AB*CD*+
A+B* C (A + (B * C)) (A + (B C *) ) A B C * +
38
The algorithm steps
1. Print operands as they arrive.
2. If the stack is empty or contains a left parenthesis “(“ on top, push the incoming operator onto the
stack.
3. If the incoming symbol is a left parenthesis “(“, push it on the stack.
4. If the incoming symbol is a right parenthesis “)”, pop the stack and print the operators until you see a
left parenthesis. Discard the pair of parentheses.
5. If the incoming symbol has higher precedence than the top of the stack, push it on the stack.
6. If the incoming symbol has equal precedence with the top of the stack, use association. If the
association is left to right, pop and print the top of the stack and then push the incoming operator. If
the association is right to left, push the incoming operator.
7. If the incoming symbol has lower precedence than the symbol on the top of the stack, pop the stack
and print the top operator. Then test the incoming operator against the new top of stack.
8. At the end of the expression, pop and print all operators on the stack. (No parentheses should remain.)
39
Infix to Postfix Conversion
Requires operator precedence information
Operands:
Add to postfix expression.
Close parenthesis:
pop stack symbols until an open parenthesis appears.
Operators:
Pop all stack symbols until a symbol of lower precedence appears. Then push the
operator.
End of input:
Pop all remaining stack symbols and add to the expression.
40
stack s
char ch, element *Infix to Postfix Rules
while(tokens are available) {
ch = read(token);
if(ch is operand) {
print ch ;
} else {
while(priority(ch) <= priority(top most stack)) {
element = pop(s);
print(element);
}
push(s,ch);
}
}
while(!empty(s)) {
element = pop(s);
print(element);
}
41
stack
infixVect
(a+b-c)*d–(e+f)
postfixVect
stack
infixVect
a+b-c)*d–(e+f)
postfixVect
(
Stack
infixVect
+b-c)*d–(e+f)
postfixVect
a
(
Stack
infixVect
b-c)*d–(e+f)
postfixVect
a
+
(
Stack
infixVect
-c)*d–(e+f)
postfixVect
ab
+
(
Stack
infixVect
c)*d–(e+f)
postfixVect
ab+
-
(
Stack
infixVect
)*d–(e+f)
postfixVect
ab+c
-
(
Stack
infixVect
*d–(e+f)
postfixVect
ab+c-
Stack
infixVect
d–(e+f)
postfixVect
ab+c-
*
Stack
infixVect
–(e+f)
postfixVect
ab+c-d
*
Stack
infixVect
(e+f)
postfixVect
ab+c–d*
-
Stack
infixVect
e+f)
postfixVect
ab+c–d*
(
-
Stack
infixVect
+f)
postfixVect
ab+c–d*e
(
-
Stack
infixVect
f)
postfixVect
ab+c–d*e
+
(
-
Stack
infixVect
)
postfixVect
ab+c–d*ef
+
(
-
Stack
infixVect
postfixVect
ab+c–d*ef+
-
Stack
infixVect
postfixVect
ab+c–d*ef+-
* Char Stack[1:n]; / Stack to hold operators Int top =
0; / stack is initially empty String E; / E is string which
contains input infix expression Infix_To_Postfix(E)
Case: x is an operator
{
while ( ISP( stack[top] ) > = ICP( x ) )
For( i = 1 to Length (E)) {
{ x = E[i]; / Get the next symbol print : Stack[ top ];
Case : x is an operand top = top - 1 ;
Print : X; continue; }
Case : x = = ‘;’ top = top + 1;
stack [ top ] = x;
while(top>0)
}
{ print: stack[top];
}
top = top – 1; }
print: ‘;’ ; return;
Case : x = = ‘)’
while ( stack[top] ! = ‘(‘ )
{
print: stack[top];
top = top - 1; }
top = top – 1;
continue; 59
Infix to Postfix Rules
Current Operator Postfix string
Expression: symbol Stack
1 A A
A * (B + C * D) + E
2 * * A
becomes 3 ( *( A
4 B *( AB
ABC D * +* E+ 5 + *(+ AB
6 C *(+ ABC
7 * *(+* ABC
8 D *(+* ABCD
Postfix notation
is also called as 9 ) * ABCD*+
Reverse Polish 10 + + ABCD*+*
Notation (RPN) 11 E + ABCD*+*E
12 ABCD*+*E+
60
Infix to postfix
* A * (B + C * D) + E
61
Algorithm to convert Infix To Postfix
* Let, X is an arithmetic expression written in infix notation. This algorithm finds the equivalent postfix
expression Y.
* Push “(“onto Stack, and add “)” to the end of X.
* Scan X from left to right and repeat Step 3 to 6 for each element of X until the Stack is empty.
* If an operand is encountered, add it to Y.
* If a left parenthesis is encountered, push it onto Stack.
* If an operator is encountered ,then:
* Repeatedly pop from Stack and add to Y each operator (on the top of Stack) which has the same precedence as or
higher precedence than operator.
* Add operator to Stack.
[End of If]
* If a right parenthesis is encountered ,then:
* Repeatedly pop from Stack and add to Y each operator (on the top of Stack) until a left parenthesis is encountered.
* Remove the left Parenthesis.
[End of If]
[End of If]
* END. 62
Infix Expression:
A+ (B*C-(D/E^F)*G)*H,
where ^ is an exponential operator.
63
int precedence(char symbol)
{
if(symbol == '^')/* exponent operator, highest precedence*/
{ return(3); }
else if(symbol == '*' || symbol == '/')
{ return(2); }
else if(symbol == '+' || symbol == '-') /* lowest precedence */
{ return(1); }
else
{ return(0); }
}
64
*Infix to prefix
Input : A * B + C / D
Output : + * A B/ C D
Output : *-A/BC-/AKL
65
Infix to Prefix
* Step 1: Reverse the infix expression i.e A+B*C will
become C*B+A.
* Note while reversing each ‘(‘ will become ‘)’ and each ‘)’
becomes ‘(‘.
* Step 2: Obtain the “nearly” postfix expression of the
modified expression i.e CB*A+.
* Step 3: Reverse the postfix expression. Hence in our
example prefix is +A*BC.
66
Step 1. Push “)” onto STACK, and add “(“ to end of the A
Step 2. Scan A from right to left and repeat step 3 to 6 for each element of A until the STACK is empty
Step 3. If an operand is encountered add it to B
Step 4. If a right parenthesis is encountered push it onto STACK
Step 5. If an operator is encountered then:
a. Repeatedly pop from STACK and add to B each operator (on the top of STACK) which has same
or higher precedence than the operator.
b. Add operator to STACK
Step 6. If left parenthesis is encontered then
a. Repeatedly pop from the STACK and add to B (each operator on top of stack until a left
parenthesis is encounterd)
b. Remove the left parenthesis
Step 7. Exit
69
Basic Idea
• Queue is an abstract data structure, somewhat similar to Stacks. Unlike
stacks, a queue is open at both its ends. One end is always used to
insert data (enqueue) and the other is used to remove data (dequeue).
70
Queue Representation
71
enqueue
dequeue
create
QUEUE
isempty
size
72
QUEUE: First-In-First-Out (FIFO)
void enqueue (queue *q, int element);
/* Insert an element in the queue */
int dequeue (queue *q);
/* Remove an element from the queue */
queue *create();
/* Create a new queue */
int isempty (queue *q);
/* Check if queue is empty */
int size (queue *q);
/* Return the no. of elements in queue */
73
Queue using Linked List
74
Basic Idea
• Basic idea:
• Create a linked list to which items would be added to one end and
deleted from the other end.
• Two pointers will be maintained:
• One pointing to the beginning of the list (point from where
elements will be deleted).
• Another pointing to the end of the list (point where new
elements will be inserted). Rear
ENQUEUE
front rear
76
Queue: Linked List Structure
DEQUEUE
front rear
77
Example :Queue using Linked List
struct qnode void enQueue(struct Queue* q, int k)
{ {
int val; // Create a new LL node
struct qnode *next; struct QNode* temp = newNode(k);
};
// If queue is empty, then new node is front and rear both
struct queue if (q->rear == NULL) {
{ q->front = q->rear = temp;
struct qnode *front, *rear;
return;
};
typedef struct queue QUEUE; }
// Add the new node at the end of queue and change rear
q->rear->next = temp;
q->rear = temp;
}
78
Example :Queue using Linked List
int size (queue *q)
{
queue *q1; // Function to remove a key from given queue q
int count=0; void deQueue(struct Queue* q)
q1=q; {
while(q1!=NULL) // If queue is empty, return NULL.
{ if (q->front == NULL)
q1=q1->next; return;
count++;
} // Store previous front and move front one node ahead
return count; struct QNode* temp = q->front;
}
q->front = q->front->next;
int peek (queue *q) // If front becomes NULL, then change rear also as NULL
{ if (q->front == NULL)
queue *q1; q->rear = NULL;
q1=q;
while(q1->next!=NULL)
q1=q1->next; free(temp);
return (q1->val); }
}
79
*Queue
Data structure with First-In First-Out (FIFO) behavior
Out
In
B A
C B A
80
*Typical Operations on Queue
REAR
Enqueue
Dequeue
81 FRONT
*Possible Implementations
Linear Arrays:
(static/dynamicaly allocated) Front=> index of the first
element -1
82
*Possible Implementations
Linear Arrays: Linear Arrays:
(static/dynamicaly allocated) (static/dynamicaly allocated)
3 7 1
Linear Arrays:
(static/dynamicaly allocated)
Queue Full!
3 7 1 8 0 9 6
83
front rear
*Possible Implementations
Linear Arrays: Linear Arrays:
(static/dynamicaly allocated) (static/dynamicaly allocated)
7 1
Linear Arrays:
(static/dynamicaly allocated)
Queue Full!
0 9 6
84
front rear
void CreateQueue(qu *q) { //define structure of a queue
q->front = -1; struct queue {
q->rear = -1; int array[MAX];
} int front;
int rear;
//create a function to add new element };
void EnQueue(qu *q, int x){
if(q->rear == (MAX - 1)){ / create a function to check whether
printf("Queue size limit reached.\n"); // the queue is empty or not
} else { void isEmpty(qu *q) {
q->array[++q->rear] = x;
printf("%i is added into the queue.\n", x); if(q->rear == q->front) {
}
} //create a function to return size of the queue printf("Queue is empty.\n");
int size(qu *q) { }
return (q->rear - q->front); else {
} printf("Queue is not empty.\n");
}
}
85
//create a function to delete front element
void DeQueue(qu *q){
if(q->rear == q->front){
printf("Queue is empty.\n");
} else {
int x = q->array[++q->front];
printf("%i is deleted from the queue.\n", x);
}
}
front rear
front
rear
[2] [5]
[1] [6]
[0] [7]
front=0
rear=0
88
*Circular Queue
[3] [4] rear = 4
[3] [4]
C D
[2] [5]
[2] [5] B
After insertion
A
[1] [6] of A, B, C, D
[1] [6]
front=0
rear=0
89
*Circular Queue
[3] [4] rear = 4
[3] [4]
C D
[2] [5]
[2] [5] B
After insertion
A
[1] [6] of A, B, C, D
[1] [6]
front=0
rear=0
After deletion of
[1] [6] of A, B
90
[0] [7]
front: index of queue-head (always empty – why?)
rear: index of last element, unless rear = front
[2] [5]
[2] [5]
92
int isfull (queue *q)
{ int isempty (queue *q)
if (q->front == ((q->rear + 1) {
%
MAX_Q_SIZE)) if (q->front == q->rear)
return 1; return 1;
return 0; return 0;
} }
93
*Operations
*Operations
element front( queue *q )
{
return q->list[(q->front + 1) % MAX_Q_SIZE];
}
front
front rearrear
• Indirect applications:-
• Auxiliary data structure for algorithms
• Component of other data structures
96