Module 4 Stack-2
Module 4 Stack-2
Structures
Module 4
(Part 1: Stack)
STACK
• A stack is an Abstract Data Type (ADT).
• Commonly used in most programming languages.
• Example – a deck of cards or a pile of plates. Real-world stack allows
operations at one end only. For example, we can place or remove a card or
plate from the top of the stack only.
• In a stack, insertion and deletion of elements is permitted only at one end.
This end is called stack TOP.
• This feature makes it LIFO data structure (Last-In-First-Out). Here, the
element which is placed (inserted ) last, is accessed first.
• Insertion of element is called PUSH operation and deletion is called POP
operation.
• A stack can be implemented by means of Array, Structure, Pointer and
Linked List.
• Stack can either be a fixed size one or it may have a sense of dynamic
resizing.
• Here, we are going to implement stack using arrays, which makes it a fixed
size stack implementation.
• A pictorial representation of stack insertion and deletion operation is as
follows.
•Since insertion and deletion is done at one end, we don’t need to traverse
the entire list for these operations. So, stack supports insertion and deletion
in O(1) time i.e. in constant amount of time.
•When stack is empty, if we try to remove an element, it is called “Stack
underflow”.
•When we add an element to a stack which is full, it is called “Stack overflow”.
•A stack can theoretically grow to an infinite size. But in practice, there is
limit. For array representation, the limit is array size whereas for linked list
representation it is the amount of available memory.
Basic Operations:
• Stack operations may involve initializing the stack, using it and then de-
initializing it. Apart from these basic stuffs, a stack is used for the following
two primary operations −
1. push() − Pushing (storing) an element on the stack.
2. pop() − Removing (accessing) an element from the stack.
To use a stack efficiently, we need to check the status of stack with the
help of the following functionality-
3. peek() − get the top data element of the stack, without removing it.
4. isFull() − check if stack is full.
5. isEmpty() − check if stack is empty.
The top pointer provides top value of the stack without actually removing
it.
ARRAY REPRESENTATION OF STACKS
• In the computer’s memory, stacks can be represented as a linear array.
• Every stack has a variable called TOP associated with it, which is used to
store the address of the topmost element of the stack. It is this position
where the element will be added to or deleted from.
• There is another variable called MAX, which is used to store the maximum
number of elements that the stack can hold.
• If TOP = NULL, then it indicates that the stack is empty and if TOP = MAX–1,
then the stack is full( as array indices start from 0).
peek() isfull() isempty()
Postfix Evaluation:
Assume we have a string of operands and operators, the steps are-
1. Scan the expression left to right.
2. Skip values or variables (operands).
3. When an operator is found, apply the operation to the preceding two operands.
4. Replace the two operands and operator with the calculated value (three symbols
are replaced with one operand).
5. Continue scanning until only a value remains, the result of the expression.
The time complexity is O(n) because each operand is scanned once, and each
operation is performed once.
Algorithm:
create a new stack
while(input stream is not empty){
token = getNextToken();
if(token instance of operand){
push(token);
} else if (token instance of operator)
op2 = pop();
op1 = pop();
result = calc(token, op1, op2);
push(result);
}
}
return pop();
Infix transformation to Postfix
This process uses a stack as well. We have to hold information that's
expressed inside parentheses while scanning to find the closing ')'. We
also have to hold information on operations that are of lower precedence
on the stack. The algorithm is:
1. Create an empty stack and an empty postfix output string/stream.
2. Scan the infix input string/stream left to right.
3. If the current input token is an operand, simply append it to the output string
4. If the current input token is an operator, pop off all operators that have equal
or higher precedence and append them to the output string; push the
operator onto the stack. The order of popping is the order in the output.
5. If the current input token is '(', push it onto the stack
6. If the current input token is ')', pop off all operators and append them to the
output string until a '(' is popped; discard the '('.
7. If the end of the input string is found, pop all operators and append them to
the output string.
Algorithm to convert an infix notation to postfix notation.
Step 1: Add “)” to the end of the infix expression
Step 2: Push “ ( “ on to the stack
Step 3: Repeat until each character in the infix notation is scanned
IF a “( “ is encountered, push it on the stack
IF an operand (whether a digit or a character) is encountered, add it to
the postfix expression.
IF a “)” is encountered, then
a. Repeatedly pop from stack and add it to the postfix
expression until a ( is encountered.
b. Discard the “(“ . That is, remove the “(“ from stack and do
not add it to the postfix expression
IF an operator is encountered, then
a. Repeatedly pop from stack and add each operator (popped from the
stack) to the postfix expression which has the same precedence or a
higher precedence than 0
b. Push the operator 0 to the stack
[END OF IF]
Step 4: Repeatedly pop from the stack and add it to the postfix expression until the stack is
empty
Step 5: EXIT
Backtracking
• Backtracking is used in algorithms in which there are steps along some
path (state) from some starting point to some goal.
• Example- Find your way through a maze/ Find a path from one point in a
graph (roadmap) to another point/ Play a game in which there are moves
to be made (checkers, chess).
• In all of these cases, there are choices to be made among a number of
options. We need some way to remember these decision points in case we
want/need to come back and try the alternative.
• Stacks can be used as part of the solution.
• Recursion is another, typically more favoured, solution, which is actually
implemented by a stack.
Implementing Parentheses Checker
• Stacks can be used to check the validity of parentheses in any algebraic
expression.
• For example, an algebraic expression is valid if for every open bracket
there is a corresponding closing bracket.
• For example, the expression (A+B} is invalid but an expression {A + (B – C)}
is valid.
Reversing a List
• A list of numbers can be reversed by reading each number from an array
starting from the first index and pushing it on a stack.
• Once all the numbers have been read, the numbers can be popped one at
a time and then stored in the array starting from the first index.
Function calls
•In function calls where we are executing function A. In the
course of its execution, function A calls another function B.
Function B in turn calls another function C, which calls
function D. Function C
•In order to keep track of the returning point of each active
Function B
function, a special stack called system stack or call stack is
used. Whenever a function calls another function, the calling Function A
function is pushed onto the top of the stack. This is because
after the called function gets executed, the control is passed
back to the calling function.
•Once function D gets completely executed, function C will
be removed from the stack for execution. The whole
procedure will be repeated until all the functions get
executed.
•The system stack ensures a proper execution order of
functions. Therefore, stacks are frequently used in situations
where the order of processing is very important, especially
when the processing needs to be postponed until other
conditions are fulfilled.