Unit 2 Stack
Unit 2 Stack
Working of Stack
Stack works on the LIFO pattern. As we can observe in the below figure
there are five memory blocks in the stack; therefore, the size of the stack
is 5.
Suppose we want to store the elements in a stack and let's assume that
stack is empty. We have taken the stack of size 5 as shown below in
which we are pushing the elements one by one until the stack becomes
full.
Since our stack is full as the size of the stack is 5. In the above cases, we
can observe that it goes from the top to the bottom when we were
entering the new element in the stack. The stack gets filled up from the
bottom to the top.
When we perform the delete operation on the stack, there is only one way
for entry and exit as the other end is closed. It follows the LIFO pattern,
which means that the value entered first will be removed last. In the
above case, the value 5 is entered first, so it will be removed only after
the deletion of all the other elements.
PUSH operation
The steps involved in the PUSH operation is given below:
POP operation
The steps involved in the POP operation is given below:
o Before deleting the element from the stack, we check whether the stack is
empty.
o If we try to delete the element from the empty stack, then
the underflow condition occurs.
o If the stack is not empty, we first access the element which is pointed by
the top
o Once the pop operation is performed, the top is decremented by 1,
i.e., top=top-1.
Applications of Stack
The following are the applications of the stack:
1. int main()
2. {
3. cout<<"Hello";
4. cout<<"javaTpoint";
5. }
As we know, each program has an opening and closing braces; when the
opening braces come, we push the braces in a stack, and when the
closing braces appear, we pop the opening braces from the stack.
Therefore, the net value comes out to be zero. If any symbol is left in the
stack, it means that some syntax occurs in a program.
o String reversal: Stack is also used for reversing a string. For example,
we want to reverse a "javaTpoint" string, so we can achieve this with the
help of a stack.
First, we push all the characters of the string in a stack until we reach the
null character.
After pushing all the characters, we start taking out the character one by
one until we reach the bottom of the stack.
o UNDO/REDO: It can also be used for performing UNDO/REDO operations.
For example, we have an editor in which we write 'a', then 'b', and then 'c';
therefore, the text written in an editor is abc. So, there are three states, a,
ab, and abc, which are stored in a stack. There would be two stacks in
which one stack shows UNDO state, and the other shows REDO state.
If we want to perform UNDO operation, and want to achieve 'ab' state,
then we implement pop operation.
o Recursion: The recursion means that the function is calling itself again.
To maintain the previous states, the compiler creates a system stack in
which all the previous records of the function are maintained.
o DFS(Depth First Search): This search is implemented on a Graph, and
Graph uses the stack data structure.
o Backtracking: Suppose we have to create a path to solve a maze
problem. If we are moving in a particular path, and we realize that we
come on the wrong way. In order to come at the beginning of the path to
create a new path, we have to use the stack data structure.
o Expression conversion: Stack can also be used for expression
conversion. This is one of the most important applications of stack. The list
of the expression conversion is given below:
o Infix to prefix
o Infix to postfix
o Prefix to infix
o Prefix to postfix
Postfix to infix
1. Increment the variable Top so that it can now refere to the next memory
location.
2. Add element at the position of incremented top. This is referred to as
adding new element at the top of the stack.
Algorithm:
1. begin
2. if top = n then stack full
3. top = top + 1
4. stack (top) : = item;
5. end
Algorithm :
1. begin
2. if top = 0 then stack empty;
3. item := stack(top);
4. top = top - 1;
5. end;
The top most node in the stack always contains null in its address field.
Lets discuss the way in which, each operation is performed in linked list
implementation of stack.
It is used when we know all the data to be It is good to use when there are dynamic
processed and require constant changes at processes. It is useful when we do not
any element. know how much data would be required.
5+6
A-B
(P * 5)
What is infix notation?
When the operator is written in between the operands, then it is known
as infix notation. Operand does not have to be always a constant or a
variable; it can also be an expression itself.
For example,
(p + q) * (r + s)
Operators Symbols
Parenthesis ( ), {}, [ ]
Exponents ^
For example:
2^2^3 = 2 ^ 8
= 256
Postfix Expression
The postfix expression is an expression in which the operator is written
after the operands. For example, the postfix expression of infix notation
( 2+3) can be written as 23+.
o Scan the expression from left to right until we encounter any operator.
o Perform the operation
o Replace the expression with its computed value.
o Repeat the steps from 1 to 3 until no more operators exist.
o Infix expression: 2 + 3 * 4
o We will start scanning from the left most of the expression. The
multiplication operator is an operator that appears first while
scanning from left to right. Now, the expression would be:
o Expression = 2 + 34*
o = 2 + 12
o Again, we will scan from left to right, and the expression would be:
o Expression = 2 12 +
o = 14
o example.
o Infix expression: K + L - M*N + (O^P) * W/U/V * T + Q
K K
+ +
L + KL
- - K L+
M - K L+ M
* -* K L+ M
N -* KL+MN
+ + K L + M
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
* +* 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+
For example, if the infix expression is 5+1, then the prefix expression
corresponding to this infix expression is +51.
a*b+c
*ab+c
Q Q
+ + Q
T + QT
* +* QT
V +* QTV
/ +*/ QTV
U +*/ QTVU
/ +*// QTVU
W +*// QTVUW
* +*//* QTVUW
) +*//*) QTVUW
P +*//*) QTVUWP
^ +*//*)^ QTVUWP
O +*//*)^ QTVUWPO
( +*//* QTVUWPO^
+ ++ QTVUWPO^*//*
N ++ QTVUWPO^*//*N
* ++* QTVUWPO^*//*N
M ++* QTVUWPO^*//*NM
- ++- QTVUWPO^*//*NM*
L ++- QTVUWPO^*//*NM*L
+ ++-+ QTVUWPO^*//*NM*L
K ++-+ QTVUWPO^*//*NM*LK
QTVUWPO^*//*NM*LK+-++
What is Recursion?
The process in which a function calls itself directly or indirectly is called
recursion and the corresponding function is called a recursive function. Using
a recursive algorithm, certain problems can be solved quite easily. Examples
of such problems are Towers of Hanoi (TOH), Inorder/Preorder/Postorder
Tree Traversals, DFS of Graph, etc. A recursive function solves a particular
problem by calling a copy of itself and solving smaller subproblems of the
original problems. Many more recursive calls can be generated as and when
required. It is essential to know that we should provide a certain case in
order to terminate this recursion process. So we can say that every time the
function calls itself with a simpler version of the original problem.
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. It has certain
advantages over the iteration technique which will be discussed later. A task
that can be defined with its similar subtask, recursion is one of the best
solutions for it. For example; The Factorial of a number.
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.
A Mathematical Interpretation
Let us consider a problem that a programmer has to determine the sum of
first n natural numbers, there are several ways of doing that but the simplest
approach is simply to add the numbers starting from 1 to n. So the function
simply looks like this,
approach(1) – Simply adding one by one
f(n) = 1 + 2 + 3 +……..+ n
but there is another mathematical approach of representing this,
approach(2) – Recursive adding
f(n) = 1 n=1
f(n) = n + f(n-1) n>1
There is a simple difference between the approach (1) and approach(2) and
that is in approach(2) the function “ f( ) ” itself is being called inside the
function, so this phenomenon is named recursion, and the function
containing recursion is called recursive function, at the end, this is a great
tool in the hand of the programmers to code some problems in a lot easier
and efficient way.
What is the base condition in recursion?
In the recursive program, the solution to the base case is provided and the
solution to the bigger problem is expressed in terms of smaller problems.
int fact(int n)
{
if (n < = 1) // base case
return 1;
else
return n*fact(n-1);
}
In the above example, the base case for n < = 1 is defined and the larger
value of a number can be solved by converting to a smaller one till the base
case is reached.
What is the difference between direct and indirect recursion?
A function fun is called direct recursive if it calls the same function fun. A
function fun is called indirect recursive if it calls another function say fun_new
and fun_new calls fun directly or indirectly. The difference between direct
and indirect recursion has been illustrated in Table 1.
// An example of direct recursion
void directRecFun()
{
// Some code....
directRecFun();
// Some code...
}
indirectRecFun2();
// Some code...
}
void indirectRecFun2()
{
// Some code...
indirectRecFun1();
// Some code...
}
What is the difference between tailed and non-tailed recursion?
A recursive function is tail recursive when a recursive call is the last thing
executed by the function. Please refer tail recursion article for details.
Fibonacci Series
Fibonacci series generates the subsequent number by adding two
previous numbers. Fibonacci series starts from two numbers − F0 & F1.
The initial values of F0 & F1 can be taken 0, 1 or 1, 1 respectively.
Fibonacci series satisfies the following conditions −
Fn = Fn-1 + Fn-2
Hence, a Fibonacci series can look like this −
F8 = 0 1 1 2 3 5 8 13
or, this −
F8 = 1 1 2 3 5 8 13 21
For illustration purpose, Fibonacci of F8 is displayed as −
Fibonacci Iterative Algorithm
First we try to draft the iterative algorithm for Fibonacci series.
Procedure Fibonacci(n)
declare f0, f1, fib, loop
set f0 to 0
set f1 to 1
display f0, f1
for loop ← 1 to n
fib ← f0 + f1
f 0 ← f1
f1 ← fib
display fib
end for
end procedure
set f0 to 0
set f1 to 1
display f0, f1
for loop ← 1 to n
fib ← f0 + f1
f 0 ← f1
f1 ← fib
display fib
end for
END
Tower of Hanoi
1. It is a classic problem where you try to move all the disks from one peg
to another peg using only three pegs.
2. Initially, all of the disks are stacked on top of each other with larger
disks under the smaller disks.
3. You may move the disks to any of three pegs as you attempt to
relocate all of the disks, but you cannot place the larger disks over smaller
disks and only one disk can be transferred at a time.