Application of Stack and Queue
Application of Stack and Queue
Dr Deepak Gupta
Assistant Professor, SMIEEE
CSED, MNNIT Allahabad, Prayagraj
Email: deepakg@mnnit.ac.in
Multiple Stack
When we implemented a stack using an array, we had seen that the size of
the array must be known in advance. If the stack is allocated less space, then
frequent OVERFLOW conditions will be encountered.
In case, we allocate a large amount of space for the stack, it will result in
sheer wastage of memory. Thus, there lies a tradeoff between the frequency
of overflows and the space allocated.
Stack A Stack B
When an array of STACK[n] is used to represent two stacks, say Stack A
and Stack B. Then the value of n is such that the combined size of both the
Stack[A] and Stack[B] will never exceed n. Stack[A] will grow from left to
right, whereas Stack[B] will grow in opposite direction i.e. right to left.
#define MAX 50
int stack[MAX];
int topA = -1;
int topB = MAX;
#include <stdio.h>
#include <malloc.h>
#define MAX 10
int stack[MAX], topA = -1, topB = MAX;
int main()
{ case 5:
int option, val; printf("\n The contents of Stack A are :\n");
do display_stackA();
{ break;
printf("\n -----Menu----- "); case 6:
printf("\n 1. PUSH a element into Stack A"); printf("\n The contents of Stack B are :\n");
printf("\n 2. PUSH a element into Stack B"); display_stackB();
printf("\n 3. POP a element from Stack A"); break;
printf("\n 4. POP a element from Stack B"); }
printf("\n 5. Display the Stack A"); }while(option != 7);
printf("\n 6. Display the Stack B"); return 0;
printf("\n 7. Exit"); }
printf("\n Enter your choice");
scanf("%d",&option);
switch(option)
{
case 1:
printf("\n Enter the value to push on stack A :");
scanf("%d",&val);
pushA(val);
break;
case 2:
printf("\n Enter the value to push on stack B:");
scanf("%d", &val);
pushB(val);
break;
case 3:
if(val != -999)
printf("\n The value popped from Stack A = %d", val);
break;
case 4:
if(val != -999)
printf("\n The value popped from Stack B = %d",val);
break;
void pushA(int val) void pushB(int val)
{ {
if(topA == topB-1) if(topB-1 == topA)
printf("\n Overflow"); printf("\n Overflow");
else else
{ {
topA+=1; topB-=1;
stack[topA] = val; stack[topB] = val;
} }
} }
• Function calls
• Recursion
• Tower of Hanoi
Reversal of string
We can reverse a string by pushing each character of the string on the stack.
After the whole string is pushed on the stack, we can start popping the
characters from the stack and get the reversed string.
We have pushed the string “SPOT” on the stack and we get the reversed
string “TOPS”.
T O P S
T
O O O
P P P P P
S S S S S S S
Program of reversing a string using stack
#include<studio.h> void push(int item)
#include< string.h> {
#include<stdlib.h> if(isFull())
{
#define MAX 20
printf(“stack overflow”);
int top = -1;
return;
char stack[MAX]; }
char pop( ); top = top + 1;
void push (char); stack_arr[top] = item;
main() }
{ char str(20);
unsigned int i; char pop( )
printf(“Enter the string”); {
gets(str); int item;
for(i =0; i<starlen(str); i++) if(top = = -1)
push(str(i); {
for(i =0; i<starlen(str); i++) printf(“stack underflow”);
str[i] = pop(); return;
printf(“Reversed string is: ”); }
puts(str); item = stack_arr(top);
} top = top-1;
return item;
}
Checking the validity of an expression containing nested parentheses
• We can use stack to check the validity of an expression that uses nested
parentheses.
• An expression will be valid if it satisfies these two conditions:
– The total number of left parentheses should be equal to the total number of
right parentheses in the expression.
– For every right parentheses there should be a left parentheses of the same type.
• [A-B*(C+D)) Invalid
• (1+5} Invalid
• [5+4*(9-2)] Valid
• [A/(B+C)*D] Valid
Procedure:
1. Initially take an empty stack.
2. Scan the symbols of expression from left to right
3. If a symbol is a left parenthesis then push it on the stack
4. If a symbol is a right parenthesis
if the stack is empty
Invalid: right parentheses are more than left parenthesis
else
pop an element from the stack.
if the popped parenthesis does not match the parentheses being scanned.
Invalid: Mismatched parenthesis.
5. After scanning all the symbols
If the stack is empty
Valid: Balanced parenthesis
else
invalid: left parentheses more than right parentheses.
[A/(B-C)*D] [A/(B-C)*D] [A/(B-C)*D] [A/(B-C)*D]
Symbol Stack Symbol Stack Symbol Stack Symbol Stack
[ A / (
(
[ [ [ [
B A- C )
( ( (
[ [ [ [
* D ]
[ [
#include <stdio.h> int check(char exp[ ])
#define MAX 30 {
int stack[MAX], top = -1; int I;
void push(char); char temp;
char pop(); for(i=0; i<strlen(exp); i++)
int match(char a, char b); {
main() if(exp[i] ==‘(‘ || exp[i] ==‘{‘ || exp[i] == ‘[‘)
{ push(exp[i]);
int valid; if(exp[i] ==‘)‘ || exp[i] ==‘}‘ || exp[i] == ‘]‘)
char exp[MAX]; if(top = = -1)
printf(“Enter an algebraic expression); {
gets(exp); printf(“Right parentheses are more than left\n)”
valid = check(exp); return 0;
if(valid = = 1) }
printf(“Valid expression”); else
else {
printf(“Invalid expression”); temp = pop( );
} if(!match(temp, exp[i]))
{
printf(“Mismatched parentheses are :”);
printf(“%c and %c\n”, temp, exp[i]);
return 0;
int match(char a, char b) }
{ }
if(a ==‘[‘ && b == ‘]’) }
return 1; if(top = -1)
if(a ==‘{‘ && b == ‘}’) {
return 1; printf(“Balanced Parentheses\n”);
if(a ==‘(‘ && b == ‘)’) return 1;
return 1; }
return 0; else
} {
printf(“left parentheses are more than right parentheses\n”);
return 0;
}
}
Notation
The way to write arithmetic expression is known as a notation.
2. Scan every character of the postfix expression and repeat Steps 3 and 4
until ) is encountered
The final number in the stack, 1, is the value of the postfix expression.
Evaluation of a Prefix Expression
Consider the following prefix notation: /+33-+47*+123.
First reverse the prefix expression is 321+*74+-33+/
Infix expression to a Postfix expression
1. Scan the infix expression from left to right.
2. If the scanned character is an operand,
put it in the postfix expression.
3. If the scanned character is a ‘(‘,
push it to the stack.
4. If the scanned character is a ‘)’,
pop the stack and output it until a ‘(‘ is encountered, and discard both the
parenthesis.
5. If the scanned character is an operator,
(a) pop the operators that have precedence greater than or equal to the precedence
of the symbol operator, and add these popped operators to the array postfix.
(b) Push the scanned symbol operator on the stack. (Assume that left parenthesis
has the least precedence).
6. After all the symbols of array infix have been scanned, pop all the operators remaining
on the stack and add them to the array postfix.
S. No. Operator Description Associativity
1 () Parentheses Left to right
2 [] Brackets Left to right
3 . Object Left to right
4 -> Pointer Left to right
5 ++ — Postfix increment and decrement Left to right
6 ++ — Prefix increment and decrement Right to left
7 – Unary plus/minus Right to left
8 !~ Logical negation and bitwise complement Right to left
9 (type) Cast Right to left
10 * Dereference operator Right to left
11 & Address of operator Right to left
12 sizeof Unary operator, returns size in bytes. Right to left
13 */% Multiplication/ division/ modulus Left to right
14 +,– Addition/ Subtraction Left to right
15 << >> Bitwise left shift/ Bitwise right shift Left to right
16 < <= Relation less than, less than or equal to Left to right
17 > >= Relational greater than, greater than or equal to Left to right
18 == != Is equal to, Not equal to Left to right
19 & Bitwise AND Left to right
20 ^ Bitwise exclusive OR Left to right
21 | Bitwise inclusive OR Left to right
22 && Logical AND Left to right
23 || Logical OR Left to right
24 ?: Ternary operator Left to right
25 = Assignment operator Right to left
26 += -= Addition/Subtraction assignment Right to left
27 *= /= Multiplication/division assignment Right to left
28 %= &= Modulus/Bitwise AND assignment Right to left
29 ^= |= Bitwise exclusive/ Bitwise inclusive OR Right to left
30 <<= >>= Bitwise left shift/ Bitwise right shift assignment Right to left
31 , Comma operator Left to right
Infix to postfix conversion
stackVect
infixVect
(A+(B*C-(D/E ^ F) *G)*H)
postfixVect
Infix to postfix conversion
stackVect
infixVect
A+(B*C-(D/E ^ F) *G)*H)
postfixVect
(
Infix to postfix conversion
stackVect
infixVect
+(B*C-(D/E ^ F) *G)*H)
postfixVect
A
(
Infix to postfix conversion
stackVect
infixVect
(B*C-(D/E ^ F) *G)*H)
postfixVect
A
+
(
Infix to postfix conversion
stackVect
infixVect
B*C-(D/E ^ F) *G)*H)
postfixVect
( A
+
(
Infix to postfix conversion
stackVect
infixVect
*C-(D/E ^ F) *G)*H)
postfixVect
( AB
+
(
Infix to postfix conversion
stackVect
infixVect
C-(D/E ^ F) *G)*H)
postfixVect
*
( AB
+
(
Infix to postfix conversion
stackVect
infixVect
-(D/E ^ F) *G)*H)
postfixVect
*
( ABC
+
(
Infix to postfix conversion
stackVect
infixVect
(D/E ^ F) *G)*H)
postfixVect
-
( ABC*
+
(
Infix to postfix conversion
stackVect
infixVect
D/E ^ F) *G)*H)
(
postfixVect
-
( ABC*
+
(
Infix to postfix conversion
stackVect
infixVect
/E ^ F) *G)*H)
(
postfixVect
-
( ABC*D
+
(
Infix to postfix conversion
stackVect
infixVect
/ E ^ F) *G)*H)
(
postfixVect
-
( ABC*D
+
(
Infix to postfix conversion
stackVect
infixVect
/ ^ F) *G)*H)
(
postfixVect
-
( ABC*DE
+
(
Infix to postfix conversion
stackVect
^ infixVect
/ F) *G)*H)
(
postfixVect
-
( ABC*DE
+
(
Infix to postfix conversion
stackVect
^ infixVect
/ ) *G)*H)
(
postfixVect
-
( ABC*DEF
+
(
Infix to postfix conversion
stackVect
infixVect
*G)*H)
postfixVect
-
( ABC*DEF^/
+
(
Infix to postfix conversion
stackVect
infixVect
G)*H)
*
postfixVect
-
( ABC*DEF^/
+
(
Infix to postfix conversion
stackVect
infixVect
)*H)
*
postfixVect
-
( ABC*DEF^/G
+
(
Infix to postfix conversion
stackVect
infixVect
*H)
postfixVect
ABC*DEF^/G*-
+
(
Infix to postfix conversion
stackVect
infixVect
H)
postfixVect
* ABC*DEF^/G*-
+
(
Infix to postfix conversion
stackVect
infixVect
)
postfixVect
* ABC*DEF^/G*-H
+
(
Infix to postfix conversion
stackVect
infixVect
postfixVect
ABC*DEF^/G*-H*+
Consider the following expression:
A+(B*C/D-E^F^I+G)/H
Its postfix will be:
Input symbol Stack Postfix
A Empty A
+ + A
( +( A
B +( AB
* +(* AB
C +(* ABC
/ +(/ ABC*
D +(/ ABC*D
– +(- ABC*D/
E +(- ABC*D/E
^ +(-^ ABC*D/E
F +(-^ ABC*D/EF
^ +(-^ ABC*D/EF^
I +(-^ ABC*D/EF^I
+ +(+ ABC*D/EF^I^-
G +(+ ABC*D/EF^I^-G
) + ABC*D/EF^I^-G+
/ +/ ABC*D/EF^I^-G+
H +/ ABC*D/EF^I^-G+H
NULL Empty ABC*D/EF^I^-G+H/+
To convert an infix expression to a prefix expression, we can use the stack data
structure. The idea is as follows:
Step 1: Reverse the infix expression. Note while reversing each ‘(‘ will become
‘)’ and each ‘)’ becomes ‘(‘.
Need of Recursion:
Recursion is an amazing technique with the help of which we can reduce the
length of our code and make it easier to read and write.
Properties of Recursion:
• Performing the same operations multiple times with different inputs.
• In every step, we try smaller inputs to make the problem smaller.
• Base condition is needed to stop the recursion otherwise infinite loop will
occur
Types of Recursion
• Any recursive function can be characterized based on:
Recursion
int fib(int n)
{
if(n ==0 || n==1)
return 1;
return (fib(n-1)+fib(n-2));
}
Tail Recursion
1. In void function, a recursive function is called tail recursion if it is the
last statement to be executed inside the function.
void display1(int n)
{
if(n ==0)
return;
printf(“%d”,n);
display1(n-1); /* Tail recursive call
}
void display2(int n)
{
if(n ==0)
return;
display2(n-1); /* Not a Tail recursive call
printf(“%d”,n);
}
2. In a non void function, if the recursive call appears in the return statement
and that call is not part of an expression then the call is tail recursive.
int fact(int n)
{
if(n ==0)
return 1;
return (n*fact(n-1)); /* Not a Tail recursive call
}
Tower of Hanoi
Step 3 − Move n-1 disks from aux(B) to destination (C) using source (A) as
the temporary pillar.
void tofh(int ndisk, char source, char temp, char dest)
{
if(ndisk == 1)
{
printf(“Move Disk %d from %c→%c\n”, ndisk, source, dest);
return;
}
tofh(ndisk-1, source,dest,temp);
printf(“Move Disk %d from %c→%c\n”, ndisk, source, dest);
tofh(ndisk-1, temp,source,dest);
}