0% found this document useful (0 votes)
22 views

Stack

Uploaded by

alwahabmalik
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

Stack

Uploaded by

alwahabmalik
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 78

Stack

Type and Data Type

● 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 data structure is the implementation for an ADT.


● In an object-oriented language such as C++, an ADT and its implementation together
make up a class.
● Each operation associated with the ADT is implemented by a member function or
method. T
● he variables that define the space required by a data item are referred to as data
members.
● An object is an instance of a class, that is, something that is created and takes up
storage during the execution of a computer program.
Stack

● 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

● You can think of the stack data


structure as the pile of plates on top
of another.
● Here, you can:
○ Put a new plate on top
○ Remove the top plate
● If you want the plate at the bottom,
you must first remove all the plates
on top. This is exactly how the stack
data structure works.
Standard Stack Operations

● 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:

There are two ways to implement a stack

1. Using array
2. Using linked list
Stack using Array
PUSH operation

1. Before inserting an element in a stack, we check whether the stack is full.


2. If we try to insert the element in a stack, and the stack is full, then the overflow
condition occurs.
3. When we initialize a stack, we set the value of top as -1 to check that the stack is
empty.
4. When the new element is pushed in a stack, first, the value of the top gets
incremented, i.e., top=top+1, and the element will be placed at the new position of
the top.
5. The elements will be inserted until we reach the max size of the stack.
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

● In the stack Implementation, a stack


contains a top pointer. which is the
“head” of the stack where pushing and
popping items happens at the head of
the list. The first node has a null in the
link field and second node-link has the
first node address in the link field and
so on and the last node address is in the
“top” pointer.
Stack using Linked List

class Node{ class Stack{


public: Node* top;
int data;
Node* next; public:
Stack(){
Node(int data){ top=NULL;
this->data=data; }
this- };
>next=NULL;
}
};
PUSH operation

● Initialise a temp node


● Check if the node is empty, if yes the
top should point to temp node
● If not, Next of temp node should
contain the value in top
● And update top pointer to contain the
4700
address of the temp node
PUSH operation

void push(int x){


Node* temp=new Node(x);
if(isEmpty()){
top=temp;
cout << x<<" PUSHED successfully"
<< endl;
}
else{
temp -> next = top;
top = temp;
cout << x<<" PUSHED successfully" << endl;
}
}
POP operation

● First Check whether the stack is empty


or not, if yes then stack underflow
occurred.
● Otherwise, store data in the top of stack.
● Make temp node that holds the address
stored in the top node
● Move forward the top node by 1 step
● Now free this temp node
POP operation

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

● An expression is a collection of operators and operands that represents a specific


value.
● Operator is a symbol which performs a particular task like arithmetic operation or
logical operation or conditional operation etc.
● Operands are the values on which the operators can perform the task. Here operand
can be a direct value, variable, constant or address of memory location.
Expression Types

● An arithmetic expression can be written in three different but equivalent notations,


i.e., without changing the essence or output of an expression.
● Based on the operator position, expressions are divided into THREE types. They
are as follows:
1. Infix Expression
2. Postfix Expression (Reverse Polish Notation)
3. Prefix Expression (Polish Notation)
Infix Expression

● In infix expression, operator is used in between the operands.


● The general structure of an Infix expression is as follows
Operand1 Operator Operand2
● Example:
Postfix 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

Sr.No. Infix Notation Prefix Notation Postfix Notation

1 a+b +ab ab+

2 (a + b) ∗ c ∗+abc ab+c∗

3 a ∗ (b + c) ∗a+bc abc+∗

4 a/b+c/d +/ab/cd ab/cd/+

5 (a + b) ∗ (c + d) ∗+ab+cd ab+cd+∗

6 ((a + b) ∗ c) - d -∗+abcd ab+c∗d-


Why postfix representation of the expression?

● Consider the expression: a + b * c + d


● The compiler first scans the expression to evaluate the expression b * c, then again
scans the expression to add a to it. The result is then added to d after another scan.
● The repeated scanning makes it very inefficient and Infix expressions are easily
readable and solvable by humans whereas the computer cannot differentiate the
operators and parentheses easily so, it is better to convert the expression to postfix(or
prefix) form before evaluation.
● The corresponding expression in postfix form is abc*+d+. The postfix expressions
can be evaluated easily using a stack.
Precedence and Associativity of Operators

Order Precedence Associativity

Highest () Left to Right

To ^ Right to Left

Lowest *, / Left to Right

+, - Left to Right
Practice Questions

● Solve the following:


1. 5+1*6
2. 1+2*5+30/5
3. 2^2^3
Infix to Postfix Conversion using Stack Data Structure

● 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 )

The final Postfix Expression is as follows:


AB + C D - *
Practise Questions

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;

int prec(char c){


if(c=='^')
return 3;
else if (c=='*' || c=='/')
Stack using Array

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

1. Create a stack to store operands (or values).


2. Scan the given expression from left to right and do the following for every scanned
element.
- If the element is an operand, push it into the stack
- If the element is an operator, pop two operands from the stack. Evaluate the
operator on these operand and push the result back to the stack
1. When the expression is ended, the number in the stack is the final answer
Example

● Consider the following Expression


Example

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;

int calculate (int num1, int num2, char op){


int result;
switch(op){
Postfix Evaluation

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;
}

You might also like