Stack
Stack
● A type is a collection of values. For example, the Boolean type consists of the values
true and false. The integers also form a type. A bank account record will typically
contain several pieces of information such as name, address, account number, and
account balance.
● A data type is a type together with a collection of operations to manipulate the type.
For example, an integer variable is a member of the integer data type. Addition is an
example of an operation on the integer data type.
Abstract Data Type (ADT)
● Abstract Data type (ADT) is a type for objects whose behavior is defined by a set of
values and a set of operations.
● The definition of ADT only mentions what operations are to be performed but not
how these operations will be implemented.
● It does not specify how data will be organized in memory and what algorithms will
be used for implementing the operations.
● It is called “abstract” because it gives an implementation-independent view.
Example
● For example, a List is an abstract data type that is implemented using a dynamic
array and linked list. A stack is implemented using Array or Linked List. A queue is
implemented using linked list-based queue, array-based queue, and stack-based
queue. A Map is implemented using Tree map, hash map, or hash table.
Data Structure
● A stack is a linear data structure that follows the principle of Last In First Out
(LIFO). This means the last element inserted inside the stack is removed first.
● Stack has one end. It contains only one pointer top pointer pointing to the topmost
element of the stack.
● A stack can be defined as a container in which insertion and deletion can be done
from the one end known as the top of the stack.
Stack
● In order to make manipulations in a stack, there are certain operations that can be
implemented:
1. push(): to insert an element into the stack
2. pop(): to remove an element from the stack
3. peek(): Returns the top element of the stack.
4. isEmpty(): Returns true is stack is empty else false
5. isFull(): Returns true if the stack is full.
6. size(): returns the size of stack
LIFO Principle of Stack
In the image, although item 3 was kept last, it was removed first. This is exactly how the
LIFO (Last In First Out) Principle works.
Implementation of Stack:
1. Using array
2. Using linked list
Stack using Array
PUSH operation
if (isFull)
return
else
increment top
stack[top] = value
size=4
POP operation
1. Before deleting the element from the stack, we check whether the stack is empty.
2. If we try to delete the element from the empty stack, then the underflow condition
occurs.
3. If the stack is not empty, we first access the element which is pointed by the top
4. Once the pop operation is performed, the top is decremented by 1, i.e., top=top-1.
POP operation
if (isEmpty)
return 0
else
temp=stack[top]
decrement top
return temp
peek operation
if (isEmpty)
return
else
return stack[top]
#include <iostream> else {
using namespace std; a[++top] = x;
#define SIZE 1000 cout << x<<"
PUSHED successfully" << endl;
class Stack { }
int top; }
int a[SIZE]; int pop(){
Stack using Array
if (isEmpty()) {
public: cout <<
Stack() { top = -1; } "Stack Underflow";
void push(int x){ return 0;
if (isFull()) { }
cout << else {
"Stack Overflow"; int
} temp=a[top--];
return temp;
}
int peek(){ int main()
if (isEmpty()) { {
cout << Stack s;
"Stack is Empty"; s.push(10);
return 0; s.push(20);
} s.push(30);
else { cout<<s.pop()<<" POPPED
Stack using Array
int x =
successfully"<<endl;
a[top];
cout << "Top element
return x;
}
is : " << s.peek() << endl;
} return 0;
bool isEmpty(){ }
return (top < 0);
}
bool isFull(){
return (top > (SIZE -
1));
Stack using Linked List
Stack using Linked List
● To implement a stack using the linked list concept, all the linked list operations
should be performed based on Stack operations LIFO(last in first out).
● The main advantage of using a linked list over arrays is that it is possible to
implement a stack that can shrink or grow as much as needed.
● Using an array will put a restriction on the maximum capacity of the array which can
lead to stack overflow.
● Here each new node will be dynamically allocated, so overflow is not possible.
Stack using Linked List
int pop(){
if (isEmpty()) {
cout << "Stack Underflow" << endl;
return 0;
}
else {
int tempData=top->data;
Node* temp = top;
top = top -> next;
delete(temp);
return tempData;
}
}
PEEK operation
● First Check whether the stack is empty or not, if yes then return
● Otherwise return the value (data part) stored in top node of stack
PEEK operation
int peek() {
if (isEmpty()) {
cout << "Stack Underflow" << endl;
return 0;
}
else {
return top->data;
}
}
#include <iostream> class Stack{
#include <cstdlib> Node* top;
using namespace std;
Stack using Linked List
public:
class Node{ Stack(){
public: top=NULL;
int data; }
Node* next;
bool isEmpty(){
Node(int data){ return
this- (top==NULL);
>data=data; }
this-
>next=NULL;
}
};
void push(int x){ int pop(){
Node* temp=new if (isEmpty()) {
Node(x); cout << "Stack
if(isEmpty()){
Stack using Linked List
Underflow" << endl;
top=temp; return 0;
cout << x<<" }
PUSHED successfully" << endl; else {
}
int tempData=top-
else{
>data;
temp -> next
= top;
Node* temp = top;
top = temp; top = top -> next;
cout << x<<" delete(temp);
PUSHED successfully" << endl; return tempData;
} }
} }
int peek() { int main(){
if (isEmpty()) { Stack s;
cout << s.push(33);
"Stack Underflow" << endl;
Stack using Linked List
s.push(22);
return 0; s.push(11);
} s.push(44);
else { cout<<s.pop()<<"
return top-
POPPED successfully"<<endl;
>data;
cout<<s.pop()<<"
}
}
POPPED successfully"<<endl;
}; cout<<"Top
Element:"<<s.peek()<<endl;
}
Applications of Stack Data Structure
Although stack is a simple data structure to implement, it is very powerful. The most
common uses of a stack are:
1. To reverse a String- Put all the letters in a stack and pop them out. Because of the
LIFO order of stack, you will get the letters in reverse order.
2. Expression Parsing - Compilers use the stack to calculate the value of expressions
like 2 + 4 / 5 * (7 - 9) by converting the expression to prefix or postfix form.
3. In browsers - The back button in a browser saves all the URLs you have visited
previously in a stack. Each time you visit a new page, it is added on top of the
stack. When you press the back button, the current URL is removed from the stack,
and the previous URL is accessed.
Applications of Stack Data Structure
4. 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.
5. 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. We can store the text in a Stack, and when you perform the
UNDO operation then pop operation is performed.
6. Balanced Parentheses: The idea is to put all the opening brackets in the stack.
Whenever you hit a closing bracket, search if the top of the stack is the opening bracket
of the same nature.
Expression Parsing
Expression
● In postfix expression, operator is used after operands. We can say that "Operator
follows the Operands".
● The general structure of Postfix expression is as follows:
Operand1 Operand2 Operator
● Example:
Prefix Expression
● In prefix expression, operator is used before operands. We can say that "Operands
follows the Operator".
● The general structure of Prefix expression is as follows:
Operator Operand1 Operand2
● Example:
Example
2 (a + b) ∗ c ∗+abc ab+c∗
3 a ∗ (b + c) ∗a+bc abc+∗
5 (a + b) ∗ (c + d) ∗+ab+cd ab+cd+∗
To ^ Right to Left
+, - Left to Right
Practice Questions
● To convert Infix Expression into Postfix Expression using a stack data structure, We can
use the following steps:
1. Scan all the symbols one by one from left to right in the given Infix Expression.
2. If the scanned symbol is operand, then directly print it to the result (Output).
3. If the stack is empty, or contain left parentheses ( on the top, push the operator into the
stack.
4. If the scanned symbol is left parenthesis '(', then Push it in to the Stack.
5. If the scanned symbol is right parenthesis ')', then Pop and print all the contents of stack
until respective left parenthesis is popped.
6. If the scanned symbol is operator (+ , - , * , / etc.,) and have higher precedence than the
element present on top of stack, push it into the stack.
Infix to Postfix Conversion using Stack Data Structure
7. If the scanned symbol is operator (+ , - , * , / etc.,) and have lower precedence than the
element present on top of stack, pop and print the top element from the stack, then again
check for the operator precedence against the new top element of the stack.
8. If the scanned symbol has the equal precedence with the top of the stack, use the rule of
associativity.
- If the associativity is L -> R, then pop and print the top of the stack, then push the
scanned symbol into the stack
- If the associativity is R -> L, then push the scanned symbol into the stack
9. At the end of expression, pop and print all the elements present in the stack.
Example
● To convert Infix Expression into Postfix Expression using a stack data structure, We
can use the following steps:
● Consider the following Infix Expression:
(A+B ) * ( C - D )
● The given infix expression can be converted into postfix expression using Stack data
Structure as follows:
Example
(A+B ) * ( C - D )
Example
(A+B)*(C-D)
Example
(A + B ) * ( C - D )
Example
(A+ B ) * ( C - D )
Example
(A+ B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
Example
(A+B ) * ( C - D )
1. A+B/C
2. A-B/C*D+E
3. K+L-M*N+(O^P)*W/U/V*T+Q
#include <bits/stdc++.h>
using namespace std;
return 2;
else if (c=='+' || c=='-')
return 1;
else
return -1;
}
string infixToPostfix(string str){
Stack s;
string result;
for(int i=0;i<str.length();i++){
char c=str[i];
if (c>='a' && c<='z' || c>='A' && c<='Z')
result+=c;
else if(s.isEmpty()||c=='(')
s.push(c);
else if(c==')'){
Stack using Array
while(s.peek()!='('){
result+=s.peek();
s.pop();
}
s.pop();
}else{
while(!s.isEmpty() && prec(s.peek())>=prec(c) &&
prec(c)!=3){
result+=s.peek();
s.pop();
}
s.push(c);
}
}
}
while (!s.isEmpty()){
result+=s.peek();
s.pop();
Stack using Array
}
return result;
}
int main(){
cout<<infixToPostfix("K+L-M*N+(O^P)*W/U/V*T+Q")<<endl;
}
Postfix Evaluation
53+82-*
Example
53+82-*
Example
53+82-*
Example
53+82-*
Example
53+82-*
Example
53+82-*
Example
53+82-*
Example
53+82-*
Practise Questions
1. 231* + 9 -
2. 23*45+*
3. 53+62/*35*+
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
case '+':
result=num2+num1;
break;
case '-':
result=num2-num1;
break;
case '*':
result=num2*num1;
break;
case '/':
result=num2/num1;
break;
case '^':
result=pow(num2,num1);
break;
}
Postfix Evaluation
return result;
}
int postfixEval(string str){
stack<int> s;
for (int i=0; i<str.length();i++){
char c=str[i];
if(c>='0' && c<='9'){
s.push(c-'0');
}
else{
int num1=s.top();
s.pop();
int num2=s.top();
s.pop();
int result=calculate(num1, num2, c);
s.push(result);
Postfix Evaluation
}
}
return s.top();
}
int main(){
cout<<postfixEval("53+62/*35*+")<<endl;
}