Unit 5
Stack
Stack
- Infix
- Prefix
- Postfix
Applications of stacks
Stack as abstract data types
Operations on stacks
The stacks of elements of any particular type may be a finite sequence of elements of that type alongside the subsequent operations:
REPRESENTATION OF A STACK
- using a one-dimensional array
- one linked list.
Array Representation of Stacks
Linked List Representation of Stacks
Algorithms for Stack Operations – PUSH, POP, PEEP
A pointer TOP keeps track of the highest element within the stack. Initially, when the stack is empty, TOP features a value of “one” then on.
Each time a replacement element is inserted within the stack, the pointer is incremented by “one” before, the element is placed on the stack. The pointer is decremented by “one” whenever a deletion is formed from the stack.
Procedure: PUSH (S, TOP, X)
This procedure inserts a component x to the highest of a stack which is represented by a vector S containing Nelements with a pointer TOP denoting the highest element within the stack.
1. [Check for stack overflow]
If TOP ≥ N
Then write (‘STACK OVERFLOW’)
Return
2. [Increment TOP]
TOP ←TOP + 1
3. [Insert Element]
[STOP] ←X
4. [Finished]
Return
Function: POP (S, TOP)
This function removes the highest element from a stack which is represented by a vector S and returns thiselement. TOP may be a pointer to the highest element of the stack.
1. [Check for underflow of stack]
If TOP = 0
Then Write (‘STACK UNDERFLOW ON POP’)
Take action in response to underflow
Return
2. [Decrement Pointer]
TOP ← TOP – 1
3. [Return former top element of stack]
Return (S[TOP + 1])
Function: PEEP (S, TOP, I)
This function returns the worth of the ith element from the highest of the stack which is represented by a vectorS containing N elements. The element isn't deleted by this function.
1. [Check for stack Underflow]
If TOP - I +1 ≤ 0
Then Write (‘STACK UNDERFLOW ON PEEP’)
Take action in response to Underflow
Exit
2. [Return Ith element from top of the stack
Return (S[TOP – I + 1])
Write an algorithm to vary the ith value of stack to value X
PROCEDURE: CHANGE (S, TOP, X, I)
This procedure changes the worth of the Ith element from the highest of the stack to the worth containing in X.
Stack is represented by a vector S containing N elements.
1. [Check for stack Underflow]
If TOP – I + 1 ≤ 0
Then Write (‘STACK UNDERFLOW ON CHANGE’)
Return
2. [Change Ith element from top of the stack]
S[TOP – I + 1] ← X
3. [Finished]
Return
Algorithm for push, pop and empty operations on stack.
Algorithm RECOGNIZE
Given an input string named STRING on alphabet ‘a’ and ‘b’ which contain blank (‘ ‘) on right most character
Function NEXTCHAR which returns subsequent symbol from STRING. This algorithm determines if an input string is of form ai bi where i>1 i.e. no of ‘a’ should be adequate to no of ‘b’. The vector S represent the stack and TOP isthe pointer to the highest element of stack. Counter may be a counter B for ‘b’ occurrence.
1. [Initialize stack and counter]
TOP←0
COUNTER_B ←0
2. [Get and stack character ‘a’ from whole string and count the occurrence of ‘b’ ]
NEXT ←NEXTCHAR(STRING)
Repeat while NEXT != ‘ ‘
IF NEXT = ‘a’
Then PUSH (S, TOP, NEXT)
Else COUNTER_B ←COUNTER_B+1
NEXT ←NEXTCHAR(STRING)
3. [Pop the stack until empty and decrement the COUNTER_B]
Repeat while TOP != 0
POP (S,TOP)
COUNTER_B←COUNTER_B-1
4. [Check for grammar]
If COUNTER_B != 0
Then write (‘INVALID STRING’)
Else write (‘VALID STRING’)
What is recursion? Write a C program for GCD using recursion.
Recursion
A procedure that contains a procedure call to itself or a procedure call to second procedure whicheventually causes the primary procedure to be called is understood as recursive procedure.
There are two important conditions that has got to be satisfied by any recursive procedure
There are two sorts of recursion
C program for GCD using recursion
#include
intFind_GCD(int, int);
void main()
{
int n1, n2, gcd;
scanf(“%d %d”,&n1, &n2);
gcd = Find_GCD(n1, &n2);
printf(“GCD of a kid and a light is %d”, n1, n2, gcd);
}
intFind_GCD(int m, int n)
{
intgcdVal;
if(n>m)
{
gcdVal = Find_GCD(n,m);
}
else if(n==0)
{
gcdVal = m;
}
else
{
gcdVal = Find_GCD(n, m%n);
}
return(gcdVal);
}
Algorithm for factorial
Algorithm: FACTORIAL
Given integer N, this algorithm computes factorial of N. Stack A is employed to store an activation record associatedwith each recursive call. Each activation record contains the present value of N and therefore the current addressRET_ADDE.TEMP_REC is additionally a record which contains two variables PARAM & ADDRESS.TOP may be a pointer to thetop element of stack A. Initially address is about to the most calling address. PARAM is about to initial value N.
1. [Save N and return Address]
CALL PUSH (A, TOP, TEMP_REC)
2. [Is the bottom criterion found?]
If N=0
Then FACTORIAL1
GO TO Step 4
Else PARAM←N-1
ADDRESS←Step 3
GO TO Step 1
3. [Calculate N!]
FACTORIAL←N * FACTORIAL
4. [Restore previous N and return address]
TEMP_REC←POP(A,TOP)
(i.e., PARAM←N, ADDRESSRET_ADDR)
GO TO ADDRESS
Multiple stacks
push(int x, intsn) –> pushes x to stack number ‘sn’ where sn is from 0 to k-1
pop(intsn) –> pops a component from stack number ‘sn’ where sn is from 0 to k-1
Method 1 (Divide the array in slots of size n/k)
Method 2 (A space-efficient implementation)
Time complexities of operations push() and pop() is O(1).
The best a part of implementing multiple stacks is, if there's a slot available in stack, then an item are often pushed in any of the stacks, i.e., no wastage of space.
Applications of stack
- Tail recursion
- Non tail recursion
- Indirect recursion
- Nested recursion
- Infix to postfix
- Prefix to postfix
- Postfix evaluations
Infix-
Prefix
Postfix
Infix isn't the sole possible thanks to develop expressions, although it's quite easy for people to know. Computers are likely to use a stack to guage expressions — and thus Reverse prefix notation is usually used because it may be a good way to easily evaluate an expression employing a stack.
Algorithm for Prefix to Postfix:
Postfix notation
- Prefix notation- operator are infixed to operands e.g.- +ab
- Infix notation - simplest way of writing e.g.-a+b
- postfix operators is prefixed to operands e.g.- ab+
Sr.No. | Infix Notation | Prefix Notation | Postfix Notation |
1 | a + b | + a b | ab+ |
2 | (a + b) ∗ c | *+abc | a b + c ∗ |
3 | a ∗ (b + c) | ∗ a + b c | a b c + ∗ |
4 | a / b + c / d | + / a b / c d | a b / c d / + |
5 | (a + b) ∗ (c + d) | ∗ + a b + c d | a b + c d + ∗ |
6 | ((a + b) ∗ c) - d | - ∗ + a b c d | a b + c ∗ d - |
Precedence
When an operator is between two operands precedence decides which operator will be first evaluated
a+b*c a+(b*c)
Associativity
Associativity is the rule where operators with the same precedence appear in an expression
S no | Operator | Operator | Precedence | Associativity |
1 | Exponentiation | ^ | Highest | Right associative |
2 | Multiplication and division | ‘*’ and ‘/’ | Second highest | Left associative |
3 | Addition and subtraction | + and - | Lowest | Left associative |
Step 1 − scan the expression from left to right
Step 2 − if it is an operand push it to stack
Step 3 − if it is an operator pull operand from stack and perform operation
Step 4 − store the output of step 3, back to stack
Step 5 − scan the expression until all operands are consumed
Step 6 − pop the stack and perform operation
Algorithm to convert infix to postfix
Algorithm: REVPOL
Given an input string INFIX containing an infix expression which has been padded on the proper with ‘)’ andwhose symbol have precedence value given by above table, a vector S used as a stack and a NEXTCHARwhich when invoked returns subsequent character of its argument. This algorithm converts INFIX into reversepolish and places the end in the string POLISH. The integer variable TOP denotes the highest of the stack.
Algorithm PUSH and POP are used for stack manipulation. The integer variable RANK accumulates the rankof expression. Finally the string variable TEMP is employed for temporary storage purpose.
1. [Initialize stack]
TOP ←1
S[TOP] ←‘(‘
2. [Initialize output string and rank count]
POLISH ←‘ ‘
RANK ←0
3. [Get first input symbol]
NEXT←NEXTCHAR (INFIX)
4. [Translate the infix expression]
Repeat thru step 7 while NEXT != ‘ ‘
5. [Remove symbols with greater precedence from stack]
IF TOP < 1
Then write (‘INVALID’)
EXIT
Repeat while G (S[TOP]) > F(NEXT)
TEMP ←POP (S, TOP)
POLISH ←POLISH O TEMP
RANK ←RANK + R(TEMP)
IF RANK <1
Then write ‘INVALID’)
EXIT
6. [Are there matching parentheses]
IF G(S[TOP]) != F(NEXT)
Then call PUSH (S,TOP, NEXT)
Else POP (S,TOP)
7. [Get next symbol]
NEXT ←NEXTCHAR(INFIX)
8. [Is the expression valid]
IF TOP != 0 OR RANK != 1
Then write (‘INVALID ‘)
Else write (‘VALID ’)
Trace the conversion of infix to postfix form in tabular form.
(i) (A + B * C / D - E + F / G / ( H + I ) )
Postfix expression is: A B C * D / + E – F G / H I + / +
Implement a stack using single linked list concept.
Implementation
The main advantage of using linked list over an arrays is that it's possible to implements a stack which will shrink or grow the maximum amount as required .
In using array will put a restriction to the utmost capacity of the array which may cause stack overflow. Here each new node are going to be dynamically allocate.
so overflow isn't possible.
Linked list implementation of stack
Adding a node to the stack (Push operation)
Create a node first and allocate memory thereto.
Deleting a node from the stack (POP operation)
Display the nodes (Traversing)
Recursion
Base condition for recursion
Recursion function for factorial
int fact(int n)
{
if (n < = 1) // base case
return 1;
else
return n*fact(n-1);
}
Recursion process
Recursion causes stack overflow
int fact(int n)
{
// wrong base case (it may cause // stack overflow).
if (n == 100)
return 1;
else
return n*fact(n-1);
}
If fact(10) is named , it'll call fact(9), fact(8), fact(7) then on but the amount will never reach 100. So, the bottom case isn't reached. If the memory is exhausted by these functions on the stack, it'll cause a stack overflow error.
Direct and indirect recursion
// An example of direct recursion
voiddirectRecFun()
{
// Some code....
directRecFun();
// Some code...
}
// An example of indirect recursion
void indirectRecFun1()
{
// Some code...
indirectRecFun2();
// Some code...
}
void indirectRecFun2()
{
// Some code...
indirectRecFun1();
// Some code...
}
Tail and non tail recursion
Allocation of memory to different function calls in recursion
Problems in backtracking
Backtrack algorithm
Backtrack(x)
if x is not a solution
return false
if x is a new solution
add to list of solutions
backtrack(expand x)
Example- Find all the possible ways of arranging 2 boys and 1 girl on 3 benches. Constraint: Girl should not be on the middle bench.
Solution There are a total of 3! = 6 possibilities. We will try all the possibilities and get the possible solutions. We recursively try all the possibilities.
Possible condition
Backtracking
Backtracking using stack rat maze problem
Recursion uses a call stack to stay the shop each recursive call then pop because the function ends. We’ll eliminate recursion by using our own stack to try to to an equivalent thing.
A node structure is employed to store the (i, j) coordinates and directions explored from this node and which direction to undertake out next.
Structure Used:
Procedure
Maze[4][5] = {
{1, 0, 1, 1, 0},
{1, 1, 1, 0, 1},
{0, 1, 0, 1, 1},
{1, 1, 1, 1, 1}
}
fx = 2, fy=3
Path Found!
The path can be: (0, 0) -> (1, 0) -> (1, 1) -> (2, 1) -> (3, 1) -> (3, 2) -> (3, 3) -> (2, 3)