DSA Chapter 4 - Stack
DSA Chapter 4 - Stack
Stack
Data Structure
DATA STRUCTURE AND ALGORITHM
CONTENTS
Stack Definition,
Stack Operations,
Stack Implementation
using array,
using linked lists,
Applications of Stacks,
Polish Notation and Expression Conversion
infix, postfix and prefix expressions using stack,
DATA STRUCTURE AND ALGORITHM
4.1. STACK
A stack is a list with the restriction that insertions and deletions can be performed in only one
A stack is also an Abstract Data Type (ADT), commonly used in most programming languages.
At any given time, we can only access the top element of a stack.
Each stack ADT has a data member, commonly named as top, which points to the topmost element in the stack.
In a stack, the element deleted from the set is the one most recently inserted:
Basic Operations
Push - Pushing (storing) an element on the stack.
Pop - Removing (accessing) an element from the stack.
Supportive operations
GetTop - reads (only reading, not deleting) an element from the top of the stack
Stack_initialization - sets up the stack in an empty condition
isEmpty - checks whether the stack is empty
isFull - checks whether the stack is full
Push Operation
The process of putting a new data element onto stack is known as a Push Operation.
Push operation involves a series of steps −
Step 1 − Checks if the stack is full.
Step 2 − If the stack is full, produces an error and exit.
Step 3 − If the stack is not full, increments top to point next empty space.
Step 4 − Adds data element to the stack location, where top is pointing.
Step 5 − Returns success.
Pop Operation
Accessing the content while removing it from the stack, is known as a Pop Operation.
Array vs linked list ?
This returns the top element of the stack without actually popping it.
This is the key difference between the pop and getTop operations.
This operation is useful as a safeguard against an attempt to pop an element from an empty
stack.
In ideal conditions, stacks should possess infinite capacity so that the subsequent elements can
always be pushed, regardless of the number of elements already present on the stack.
However, computers always have finite memory capacity, and we do need to check the stack_full
Can be implemented using both a static data structure (array) and a dynamic data structure
(linked list).
Array implementation
It is very simple to manage a stack when represented using an array. (ordered elements)
One of the two sides of the array can be considered as the top (upper) side and the other as the
bottom (lower)
the upper side is most commonly used
The first element is stored at Stack[0], the second element at Stack[1]…..last Stack[n-1]
Associated with the array will be an integer variable, top, which points to the top element in the
stack.
The initial value of top is -1 when the stack is empty.
It can hold the elements from index 0, and can grow to a maximum of n - 1 as this is a static stack using
arrays.
the push() function takes argument val i.e. value to be pushed into the stack.
If a top is greater than or equal to n, there is no space in a stack and overflow is
printed. Otherwise, val is pushed into the stack.
CONT…
The pop() function pops the topmost value of the stack, if there is any value.
If the stack is empty then underflow is printed.
CONT…
In linked list implementation of stack, the nodes are maintained non contiguous in the memory.
Stack is said to be overflown if the space left in the memory is not enough to create a node.
Pushing an element to a stack in linked list implementation is different from that of an array
implementation. In order to push an element onto the stack, the following steps are involved.
2. If the list is empty then the item is to be pushed as the start node of the list. This includes
assigning value to the data part of the node and assign null to the address part of the node.
3. If there are some nodes in the list already, then we have to add the new element in the beginning
of the list (to not violate the property of the stack). For this purpose, assign the address of the starting
element to the address field of the new node and make the new node, the starting node of the list.
Deleting a node from the linked list implementation of stack is different from that in the array
implementation. In order to pop an element from the stack, we need to follow the following steps
1. Check for the underflow condition: The underflow condition occurs when we try to pop from
an already empty stack. The stack will be empty if the head pointer of the list points to null.
2. Adjust the head pointer accordingly: In stack, the elements are popped only from one end,
therefore, the value stored in the head pointer must be deleted and the node must be freed. The
next node of the head node now becomes the head node.
Displaying all the nodes of a stack needs traversing all the nodes of the linked list organized in
the form of stack. For this purpose, we need to follow the following steps.
2. Move the temporary pointer through all the nodes of the list and print the value field attached
to every node.
• the structure Node is used to create the linked list that is implemented as a
stack
struct Node {
int data;
Node *next;
};
Node* top = NULL;
PUSH Operation: push function void push(int val)
inserts an element (or new node) at the
front of the list. {
•There is no need to test whether or not Node *temp = new(Node)
stack is full (dynamic allocation of space) temp->data = val;
because there is no upper limit.
temp->next = top;
top = temp;
}
POP Operation: POP
void pop()
operation performs the {
if(top==NULL)
following function. cout <<"Stack Underflow"<<endl;
• If stack is empty, it prints a else
{
warning message and halts cout <<"The popped element is "<< top->data
program execution. <<endl;
top = top->next;
• Removes the element at the }
front of the list. }
4.4. APPLICATION OF STACK
How to generate machine language instructions that could properly evaluate any arithmetic
expression? X = (A/B + C x D - F x G/Q)the order in which the operations are to be carried out?
Might have several meanings, and even if the meanings were uniquely defined, it is still difficult
Fortunately, with the help of stack we can solve the problem in both elegant and simple way.
The Polish Mathematician Jan Lukasiewicz suggested a notation called Polish notation, which gives
two alternatives to represent an arithmetic expression, namely the postfix and prefix notations.
The fundamental property of Polish notation is that the order in which the operations are to be
performed is determined by the positions of the operators and operands in the expression.
Hence, the advantage is that parentheses is not required while writing expressions in Polish notation.
The conventional way of writing the expression is called infix, because the binary operators occur
In postfix notation, the operator is written after its operands, whereas in prefix notation, the
Evaluation of an infix expression using a computer needs proper code generation by the compiler
without any ambiguity and is difficult because of various aspects such as the operator’s priority and
associativity.
1. The need for parenthesis as in an infix expression is overcome in postfix and prefix notations.
3. The order of evaluation depends on the position of the operator but not on priority and associativity.
4. The expression evaluation process is much simpler than attempting a direct evaluation from the infix notation.
E = A/ B ^ C + D \ E - A \ C
2. Let us move all operators to the corresponding right parenthesis and replace the same.
3. Now let us eliminate all parentheses. We get the postfix equivalent of the infix expression.
E(postfix) = ABC ^/ DE x+ AC x -
DATA STRUCTURE AND ALGORITHM
EXAMPLE: MANUALLY CONVERTING INFIX TO PREFIX
E = A/B ^ C + D \ E - A \ C
2. Let us move all operators to the corresponding right parenthesis and replace the same.
3. Now let us eliminate all parentheses. We get the prefix equivalent of the infix expression.
E(prefix) = - +/ A ^ BC x DE x AC
DATA STRUCTURE AND ALGORITHM
ALGORITHM TO CONVERT AN INFIX TO A POSTFIX (ALSO TO
PREFIX)
The order of the operand remains the same in the infix and the postfix notations.(from observation)
Hence, the operands from the infix expression can be immediately sent to the output as they occur.
To handle the operators, the operands are stored in the stack until the right moment and they are
unstacked (removed from the stack); they are then passed to the output.
Try 1
If in stack operator priority is greater than the incoming operator, pop the operator otherwise push it
E = A x B + C#.
Convert the following infix expressions to their equivalent postfix expression, show the sequence
of push and pop operations.
1.
X = A ^ B ^ C
When an operator is at the top of the stack or in an expression (current token), they are to be
Hence, each operator is to be assigned two priorities—the incoming priority (ICP) and the in-stack
priority (ISP).
In previous examples, we observed that the lower priority operators should spend more time in
the stack and the higher priority operators should be popped out earlier .
To achieve this, we need to assign the appropriate ICPs and ISPs to the operators.
DATA STRUCTURE AND ALGORITHM
Points to be Taken into Consideration While Assigning ICPs &
ISPs:
1. Higher priority operators should be assigned higher values of ISP and ICP.
2. For right associative operators, ISP should be lower than ICP. For example, A ^ B ^ C should
generate ABC^^, which means (A) ^ (B ^ C).
4. The ISP and ICP should be equal for left associative operators.
The following are the steps involved in the evaluation 5. If the character is an operator and if ICP >
of an expression. ISP
1. Assign priorities to all operators and define
then push the operator
associativity (left or right).
2. Assign appropriate values of ICPs and ISPs else
accordingly. For left associative operators, assign while(ICP <= ISP)
equal ISP and ICP. For right associative operators,
assign higher ICP than ISP. For example, assign a pop the operator and
higher ICP for ‘^’. display it.
3. Scan the expression from left to right, character by end while
character, till the end of expression.
Stack the incoming operator
4. If the character is an operand, then display the
same. 6. Continue till end of expression
DATA STRUCTURE AND ALGORITHM The expression could be in one of the three forms—
infix, postfix, or prefix.
INFIX TO POSTFIX CONVERSION ALGORITHM
Consider a mathematical expression that includes several sets of nested parentheses. For example,
To ensure that the parentheses are nested correctly, we need to check that
1. There are equal numbers of right and left parentheses
2. Every right parenthesis is preceded by a matching left parenthesis.
To solve this problem, let us define the parentheses count = the number of left parenthesis minus the
number of right parenthesis
The two conditions that must hold if the parentheses in an expression form an admissible pattern are
as follows:
1. The parenthesis count at each point in the expression is non-negative.
2. The parenthesis count at the end of the expression is 0.
DATA STRUCTURE AND ALGORITHM
CONT.…
Whenever a left parenthesis is encountered, it is pushed onto the stack, and whenever a right
In addition, when the end of the string is reached, the stack must be empty; otherwise, the string
is declared to be invalid.
Recursive programs are most inefficient as regards their name and space complexities.
Hence, there is a need to convert them into iterative ones. To achieve this conversion stacks need
to be used.
To convert a number from decimal to binary, we simply divide the number by 2 until a quotient
of 0 is reached.
Then, use the successive remainders in reverse order as the binary representation.