Unit 2 Stack
Unit 2 Stack
Stack is a linear data structure that follows a particular order in which the operations are
performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies
that the element that is inserted last, comes out first and FILO implies that the element that is
inserted first, comes out last.
There are many real-life examples of a stack. Consider an example of plates stacked over one
another in the canteen. The plate which is at the top is the first one to be removed, i.e. the plate
which has been placed at the bottommost position remains in the stack for the longest period of
time. So, it can be simply seen to follow LIFO(Last In First Out)/FILO(First In Last Out) order.
Stack mainly supports push(insert an element to the top of stack), pop(remove an element from the
top of stack) and peek(return top element without removing it) operations.
push(): It stacks up a new item. A stack overflow circumstance is when the stack is completely full.
Time Complexity is O(1)
1. begin
2. if stack is full
3. return
4. endif
5. else
6. increment top
7. stack[top] assign value
8. end else
9. end procedure
pop() : It takes something out of the stack. In the opposite sequence from which they were pushed, the
things are popped. The condition is referred to as an underflow if the stack is empty. Time Complexity is
O(1)
1. begin
2. if stack is empty
3. return
4. endif
5. else
6. store value of stack[top]
7. decrement top
8. return value
9. end else
10. end procedure
#include <stdio.h>
#define N 5
int top=-1;
int stack[5];
}
}
int peek()
{ int item ;
if(top==-1)
{
printf("\nunderflow");
}
else
{
item=stack[top];
return item;
}
}
void display()
{
for (int i = top;i>=0;i--)
printf("\n%d ",stack[i]);
}
void main()
{
push(10);
push(20);
printf("\nPeek = %d",peek());
display();
pop();
printf("\nPeek = %d",peek());
pop();
pop();
display();
}
Stack Applications:
1. Infix to Postfix Conversion
2. Postfix Expression Evaluation
3. Recursion
4. DFS(Depth First Search) – to be covered in graph unit
5. Undo Operation (real life example)
2nd Step: Here i = 1 and exp[i] = ‘+’ i.e., an operator. Push this into the stack. postfix =
“a” and stack = {+}.
3rd Step: Now i = 2 and exp[i] = ‘b’ i.e., an operand. So add this in the postfix
expression. postfix = “ab” and stack = {+}.
Add ‘b’ in the postfix
4th Step: Now i = 3 and exp[i] = ‘*’ i.e., an operator. Push this into the stack. postfix =
“ab” and stack = {+, *}.
5th Step: Now i = 4 and exp[i] = ‘c’ i.e., an operand. Add this in the postfix
expression. postfix = “abc” and stack = {+, *}.
Add ‘c’ in the postfix
6th Step: Now i = 5 and exp[i] = ‘+’ i.e., an operator. The topmost element of the stack has
higher precedence. So pop until the stack becomes empty or the top element has less
precedence. ‘*’ is popped and added in postfix. So postfix = “abc*” and stack = {+}.
Now top element is ‘+‘ that also doesn’t have less precedence. Pop it. postfix = “abc*+”.
Pop ‘+’ and add it in postfix
7th Step: Now i = 6 and exp[i] = ‘d’ i.e., an operand. Add this in the postfix
expression. postfix = “abc*+d”.
Add ‘d’ in the postfix
Final Step: Now no element is left. So empty the stack and add it in the postfix
expression. postfix = “abc*+d+”.
K K
+ +
L + KL
- - K L+
M - K L+ M
* -* K L+ M
N -* KL+MN
+ + K L + M N*
K L + M N* -
( +( K L + M N *-
O +( KL+MN*-O
^ +(^ K L + M N* - O
P +(^ K L + M N* - O P
) + K L + M N* - O P ^
* +* K L + M N* - O P ^
W +* K L + M N* - O P ^ W
/ +/ K L + M N* - O P ^ W *
U +/ K L + M N* - O P ^W*U
/ +/ K L + M N* - O P ^W*U/
V +/ KL + MN*-OP^W*U/V The
final
* +* KL+MN*-OP^W*U/V/
T +* KL+MN*-OP^W*U/V/T
+ + KL+MN*-OP^W*U/V/T*
KL+MN*-OP^W*U/V/T*+
Q + KL+MN*-OP^W*U/V/T*Q
KL+MN*-OP^W*U/V/T*+Q+
postfix expression of infix expression (K + L - M*N + (O^P) * W/U/V * T + Q) is KL+MN*-
OP^W*U/V/T*+Q+.
1. While reading the expression from left to right, push the element in the stack if it
is an operand.
2. Pop the two operands from the stack, if the element is an operator and then
evaluate it.
3. Push back the result of the evaluation. Repeat it till the end of the expression.
Expression: 456*+
Algorithm for Evaluation of Prefix Expression
1. Read prefix expression Right to Left
2. If operand is encountered, push it onto Stack
[End If]
3. If operator is encountered, Pop two elements
1. A -> Top element
2. B-> Next to Top element
3. Evaluate A operator B
4. Push A operator B onto Stack
4. Set result = pop
5. END
Q. What is the outcome of the given prefix expression: +, -, *, 3, 2, /, 8, 4, 1.
Asn: 5
Detailed Solution:
3. Recusrsion:
Recursion In this section we are going to discuss recursion which is an implicit application of
the STACK ADT.
A recursive function is defined as a function that calls itself to solve a smaller version of its task
until a final call is made which does not require a call to itself. Since a recursive function
repeatedly calls itself, it makes use of the system stack to temporarily store the return address and
local variables of the calling function.
Therefore, recursion is defining large and complex problems in terms of smaller and more easily
solvable problems. In recursive functions, a complex problem is defined in terms of simpler
problems and the simplest problem is given explicitly.
Therefore, 5! = 5 X 4 X 3!
Expanding further 5! = 5 X 4 X 3 X 2 X 1!
We know,1! = 1
Now if you look at the problem carefully, you can see that we can write a recursive function to
calculate the
Now if you look at the problem carefully, you can see that we can write a recursive
function to calculate the factorial of a number. Every recursive function must have a base
case and a recursive case. For the factorial function
Base case is when n = 1, because if n = 1, the result will be 1 as 1! = 1.
Recursive case of the factorial function will call itself but with a smaller value of n, this
case can be given as factorial(n) = n × factorial (n–1)
Look at the following program which calculates the factorial of a number recursively.
Programming Example
Write a program to calculate the factorial of a given number.
#include <stdio.h>
int Fact(int); // FUNCTION DECLARATION
int main()
{
int num, val;
printf("\n Enter the number: ");
scanf("%d", &num);
val = Fact(num);
printf("\n Factorial of %d = %d", num, val);
return 0; }
int Fact(int n)
{
if(n==1) return 1;
else return (n * Fact(n–1));
}
Output Enter the number: 5
Factorial of 5 = 120
1. Direct Recursion
2. Indirect Recursion
3. Tail Recursion
4. No Tail/ Head Recursion
3. 1. Direct Recursion
When a function calls itself within the same function repeatedly, it is called the direct recursion.
1. fun()
2. {
3. // write some code
4. fun();
5. // some code
6. }
In the above structure of the direct recursion, the outer fun() function recursively calls the inner
fun() function, and this type of recursion is called the direct recursion.
//Direct Recursion
#include <stdio.h>
void print(int n)
{
if(n < 1) //Base Condition
return;
else
print(n-1); //Direct recursion involves a function calling itself directly
printf("%d ",n);
}
int main()
{
print(5);
return 0;
}
O/P: 1 2 3 4 5
When a function is mutually called by another function in a circular manner, the function is
called an indirect recursion function.
1. fun1()
2. {
3. // write some code
4. fun2()
5. }
6. fun2()
7. {
8. // write some code
9. fun3()
10. // write some code
11. }
12. fun3()
13. {
14. // write some code
15. fun1()
16. }
In this structure, there are four functions, fun1(), fun2(), fun3() and fun4(). When the fun1()
function is executed, it calls the fun2() for its execution. And then, the fun2() function starts its
execution calls the fun3() function. In this way, each function leads to another function to makes
their execution circularly. And this type of approach is called indirect recursion.
//InDirect Recursion
#include <stdio.h>
void print1(int n); //function declaration
void print2(int n); //function declaration
void print1(int n)
{
if(n < 1) //Base Condition
return;
else
print2(n-1); //print1 calls print2
printf("%d ",n);
}
void print2(int n)
{
if(n < 1) //Base Condition
return;
else
print1(n-1); //print2 calls print1
printf("%d ",n);
}
int main()
{
print1(5);
return 0;
}
O/P: 1 2 3 4 5
A recursive function is called the tail-recursive if the function makes recursive calling itself, and
that recursive call is the last statement executes by the function. After that, there is no function or
statement is left to call the recursive function.
Program
1. #include <stdio.h>
2. // function definition
3. void fun1( int num)
4. {
5. // if block check the condition
6. if (num == 0)
7. return;
8. else
9. printf ("\n Number is: %d", num); // print the number
10. return fun1 (num - 1); // recursive call at the end in the fun() function
11. }
12. int main ()
13. {
14. fun1(7); // pass 7 as integer argument
15. return 0;
16. }
Output
Number is: 7
Number is: 6
Number is: 5
Number is: 4
Number is: 3
Number is: 2
Number is: 1
3.4 Non-Tail / Head Recursion
A function is called the non-tail or head recursive if a function makes a recursive call itself, the
recursive call will be the first statement in the function. It means there should be no statement or
operation is called before the recursive calls. Furthermore, the head recursive does not perform
any operation at the time of recursive calling. Instead, all operations are done at the return time.
Program
1. #include <stdio.h>
2. void head_fun (int num)
3. {
4. if ( num > 0 )
5. {
6. // Here the head_fun() is the first statement to be called
7. head_fun (num -1);
8. printf (" %d", num);
9. }
10. }
11. int main ()
12. {
13. int a = 5;
14. printf (" Use of Non-Tail/Head Recursive function \n");
15. head_fun (a); // function calling
16. return 0;
17. }
Output