UNIT II new
UNIT II new
Stack ADT – Stack Model - Implementations: Array and Linked list - Applications - Balancing symbols -
Evaluating arithmetic expressions - Conversion of Infix to postfix expression- Queue ADT – Queue Model -
Implementations: Array and Linked list - applications of queues - Priority Queues - Binary Heap –
Applications of Priority Queues.
STACK ADT
A stack is a list with the restriction that inserts and deletes can be performed in only one position, namely
the end of the list called the top. Stacks are known as LIFO (Last In First Out) lists.
OPERATIONS ON STACK
There are three basic operations on a stack:
PUSH – This operation is used to insert an element to the stack.
POP – This operation is used to delete the most recently inserted element.
PEEK- This operation is used to return the topmost element of the stack.
The push and Pop operation can be represented as picture as follows,
IMPLEMENTATION OF STACK
Stack can be implemented by using the two ways.
1. Array implementation of Stack
2. LinkedList implementation of Stack
Array Implementation of Stack
A Stack is defined as a pointer to a structure. The structure contains 2 fields namely top_of_stack and
stack_size. In array implementation, the stack is formed by using the array. All the operations regarding the
stack are performed using arrays.
CONDITIONS ON STACK:
1. isFull()
if(top==MAX-1)
cout<<“Stack OVERFLOW or FULL”;
if(top==-1)
cout<<“Stack is empty”;
G.Vasukidevi 1
PUSH
Adding an element into the top of the stack is referred to as push operation. Push operation involves following
steps.
ALGORITHM FOR PUSH OPERATION
1. Check for the Top pointer value.
2. Check the isFull() condition.
3. If condition is true discard the operation.
4. If condition is false, Increment the Top pointer by 1 and Push the element in that Top pointer location. This
is referred to as adding new element at the top of the stack.
Code:
void push(int st[],int val)
{
if(top==Max-1)
{
cout<<“Stack is FULL”;
return -1;
}
else
{
top++;
st[top]=val;
}
}
G.Vasukidevi 2
Code:
void pop(int st[])
{
if(top==-1)
{
cout<<“Stack Underflow or empty”;
return -1;
}
else
{
int x=st[top];
cout<<“\n The Deleted Element is ”<<x;
top--;
}
}
Peek operation-Returning the Topmost element in Stack
Peek() is one of a stack operation that returns the value of the top most element of the stack without deleting
that element from the stack.
Code:
int peek(int st[])
{
if(top==-1)
{
cout<<“\n Stack is Empty”;
return -1;
}
else
{
return st[top];
}
}
LINKED LIST REPRESENTATION OF STACK
A Linked List is a Data Structure which consists of two parts:
struct node
{
int data;
struct node *next; // The pointer which gives the location of the next node in the list.
};
struct node *top=NULL;
Stack can also be represented by using a linked list. We know that in the case of arrays we face a
limitation , i.e , array is a data structure of limited size. Hence before using an array to represent a stack we
will have to consider an enough amount of space to suffice the memory required by the stack.
G.Vasukidevi 3
Operations on Linked list implementation of Stack
1. Push
2. Pop
3. Peek
After Push
G.Vasukidevi 4
CODE:
void push ()
{
int val;
struct node *new =(struct node*)malloc(sizeof(struct node));
cin>>val;
if(top==NULL)
{
new->val = val;
new -> next = NULL;
top=new;
}
else
{
new->val = val;
new->next = top;
top=new;
}
}
POP operation- Deleting a node from the stack
Deleting a node from the top of stack is referred to as pop operation. 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.
Time Complexity: o(n)
Before Pop
After Pop
G.Vasukidevi 5
void pop()
{
struct node *t;
if (top == NULL)
{
cout<<"Stack is empty or Underflow"<<endl;
return -1;
}
else
{
t=top;
top = top->next;
free(t);
}
}
Peek operation
Display the last element in the stack.
CODE
void peek()
{
if (top == NULL)
{
cout<<" Stack is empty or Underflow"<<endl;
}
else
{
cout<<top->data;
}
}
Applications of Stacks
The Application of Stacks are:
1. Reverse a list
2. Parenthesis Checker
3. Conversion of Infix Expression to Postfix Expression
4. Evaluation of Postfix Expression
5. Conversion of infix to prefix expression
6. Evaluation of Prefix Expression
7. Recursion
8. Tower of Hanoi
G.Vasukidevi 7
b. If it is a close parenthesis,
then if the stack is empty
report an error,
otherwise pop one parenthesis from stack.
d. if the parenthesis which is popped from stack is not matching with corresponding opening parenthesis,
then report an error.
3. At the end of the file, if the stack is not empty report an error.
Example 1:
[a-{b+(c+d)+e}-f]
G.Vasukidevi 8
Example 2:
{(A+B)-[(C-D)*E]
2. Conversion of Infix expression to postfix expression:
Expression:
It is the combination of operand and operator.
Eg:
a+b*c
Types of Expression:
1. Infix Expression
Operator should be in between the operands.
Syntax: operand 1 operator operand2
Eg:
a+b
2. Postfix Expression
Operator should be after the operands.
Syntax: operand 1 operand2 operator
Eg:
ab+
3. Prefix Expression
Operator should be placed before the operands.
Syntax: operator operand 1 operand2
Eg:
+ab
Steps to be followed for converting infix expression to postfix:
1. Make the stack empty.
2. Scan the infix expression, character by character from left to right until the end of an expression.
3. If the scanned character is an open parenthesis, then push that parenthesis into the stack.
4. If the scanned character is an operand (whether a digit or a character), then add it to the output (postfix
expression).
5. If the scanned character is a close parenthesis, then
a. Repeatedly pop the elements (operators) from the stack till corresponding closing parenthesis and
add it to the output (postfix expression).
b. Discard the opening parenthesis which is popped from the stack and do not add it to the postfix
expression.
6. If the scanned character is an operator, then
a. If the scanned operator is lesser precedence than the operator in the top of the stack, then
pop the operator from stack and add that operator (popped from the stack) to the
postfix expression. Push the scanned operator to the stack.
b. If the scanned operator is greater precedence than the operator in the top of the stack, then push
the scanned operator into the stack.
6. Repeatedly pop from the stack and add it to the postfix expression until the stack is empty.
G.Vasukidevi 9
Example 1:
Convert the following infix expression to postfix expression [(a+b) *(c+d/f)] - g
Step 1: When [is encountered, push it onto the stack
Stack Output
Step 2: When ( is encountered , push it onto the stack
Stack Output
Step 3: When a is encountered, it is an operand so display it on the output (postfix expression)
Stack Output
Step 4: When + is encountered, it is an operator so push it on to the stack.
Stack Output
Step 5: When b is encountered, it is an operand so display it on the output (postfix expression)
Stack Output
Step 6: When ) is encountered , pop the stack till corresponding ( and display all the symbols on the output .
Stack Output
Step 7: When * is encountered, it is an operator so push it on to the stack.
G.Vasukidevi 10
Stack Output
Step 8: When ( is encountered, push it on to the stack.
Stack Output
Step 9: When c is encountered, it is an operand so display it on the output (postfix expression
Stack Output
Step 10: When + is encountered, it is an operator so push it on to the stack.
Stack Output
Step 11: When d is encountered, it is an operand so display it on the output (postfix expression)
Stack Output
Step 12: When / is encountered, it is an operator so push it on to the stack.
Stack Output
Step 13: When f is encountered, it is an operand so display it on the output (postfix expression)
G.Vasukidevi 11
Stack Output
Step 14: When ) is encountered, pop the stack till corresponding ( is seen on the stack and display all the
popped symbols on the output (postfix expression)
Stack Output
Step 15: When ] is encountered, pop the stack till corresponding [ is seen on the stack and display all the
popped symbols on the output (postfix expression)
Stack Output
Step 16: When - is encountered, it is an operator so push it on to the stack.
Stack Output
Step 17: When g is encountered, it is an operand so display it on the output (postfix expression)
Stack Output
Step 18: We have reached the end of the infix expression, hence pop the stack till it becomes empty and
display the popped symbols on the output.
Stack Output
G.Vasukidevi 12
Example 2:
Convert the following infix expression into postfix expression using the algorithm given below
(A – (B / C + (D % E * F) / G)* H)
Steps to perform infix to Postfix:
Example 3:
Consider the following Infix Expression to be converted into Postfix Expression...
D=A+B*C
• Step 1 - The Operators in the given Infix Expression : = , + , *
• Step 2 - The Order of Operators according to their preference : * , + , =
• Step 3 - Now, convert the first operator * ----- D = A + B C *
• Step 4 - Convert the next operator + ----- D = A BC* +
• Step 5 - Convert the next operator = ----- D ABC*+ =
Finally, given Infix Expression is converted into Postfix Expression as follows... D A B C * + =
Example 4:
Convert the following Infix Expression to postfix expression... ( A + B ) * ( C - D )
Example 5:
Convert the following Infix Expression to postfix expression A – (B / C + (D % E * F) / G)* H
G.Vasukidevi 13
Evaluation of Postfix Expression using Stack:
A postfix expression can be evaluated using the Stack data structure. To evaluate a postfix expression
using Stack data structure we can use the following steps...
Algorithm:
1. Read all the symbols one by one from left to right in the given Postfix Expression
2. If the reading symbol is operand, then push it on to the Stack.
3. If the reading symbol is operator (+, - , *, / etc.),
a. Then perform TWO pop operations and store the two popped operands in two
variables (operand1 and operand2).
b. Then perform operation using the read operator, operand1 & operand2 and push result back
on to the Stack.
4. Finally perform a pop operation and display the popped value as a final result.
Example:
Consider the following Example:
Infix Expression: (5+3) * (8-2)
Postfix Expression: 5 3 + 8 2 - *
G.Vasukidevi 14
3. Function Call
A recursive function is defined as a function that calls itself to solve a smaller version of its task until
a final call is made which does not require a call to itself. Since a recursive function repeatedly calls itself,
it makes use of the system stack to temporarily store the return address and local variables of the calling
function. When there is a function call, all the important information that needs to be saved, such as register
values and the return address is saved (called as either an activation record or stack frame.
Example: The program to find the factorial of a number
QUEUE ADT
A queue is an ordered collection of items where insertion is done at a end called the rear and deletion
is done at the other end called front.
Deletion Insertion
FRONT REAR
Fig 2.5:Queue ADT
Like stacks, queues are also lists, where insertion is done at one end and deletion is performed at the other end.
The technique or discipline followed by queue is FIFO(First In First Out).The first element inserted in the queue
will be the first element to be deleted.
G.Vasukidevi 15
The primitive operations of queue are
enqueue: inserts an element at the end of the list called rear end.
dequeue: deletes the element at the start of the list called the front end.
DEQUEUE(Q) ENQUEUE(X,Q)
QUEUE(Q)
10 20 30
n=5
FRONT REAR
Operations
1. Enqueue (Insertion) – Inserting an element into the queue (at rear)
2. Dequeue (Deletion) – Deleting an element from the queue (at front)
CONDITIONS ON QUEUE:
isFull()
if(rear==MAX-1)
cout<<“Queue is OVERFLOW or FULL”;
if(front==-1)
cout<<“Queue is empty”;
Enqueue(insertion)
1) Elements are inserted at the rear portion of queue.
2) If the queue is full no more elements can be inserted resulting in overflow condition.
3) If the queue is not full then the rear pointer is incremented and the item is inserted.
G.Vasukidevi 16
Enqueue
Algorithm
Step 1: Check if the queue is full
Step 2: If the queue is full(rear==MAX-1), produce overflow error or queue full error and exit
Step 3: Else If the queue is empty (front==-1 && rear==1) make front=rear=0
Step 4: Else increment rear (rear=rear+1)
Step 5: Add data element to the queue location, where the rear is pointing.
Routine
void enqueue(int val)
{
if(rear>=MAX-1)
cout<<“Queue overflow!”<<endl;
else if(front==1 && rear==-1)
{
front=rear=0; -1
q[rear]=val;
}
else
{
rear++;
q[rear]=val;
}
}
Dequeue(deletion)
1) Elements are deleted from the front
2) If the queue is empty it results in underflow condition
3) If the queue is not empty, delete the element from front.
0 1 2 3 4
10 20 30
n=5
G.Vasukidevi 17
FRONT REAR
0 1 2 3 4
20 30
n=5
Dequeue REAR
FRONT
Algorithm
Step 1: Check if the queue is empty
Step 2: If the queue is empty, (front==1 && rear==-1), then produce underflow error and exit.
Step 3: If the queue has only one element (front==rear), then access the data and make front=rear=-1
Step 4: If the queue is not empty, access the data where front is pointing.
Step 4: Increment front pointer to point to the next available data element
Enqueue Dequeue
void display()
{
if(front==-1 && rear==-)
cout<<“Queue empty or underflow”<<endl;
else
{
for(i=front; i<= rear; i++)
cout<<q[i]<<endl;
}
}
LINKED LIST IMPLEMENTATION OF QUEUE ADT
A queue is an ordered collection of items where insertion is done at a end called the rear and deletion is done at
the other end called front. The technique or discipline followed by queue is FIFO (First In First Out) The first
element inserted in the queue will be the first element to be deleted.
DEQUEUE(Q) ENQUEUE(X,Q)
QUEUE(Q)
isEmpty()
if(front==NULL)
cout<<”queue is empty”;
Operations
1. Enqueue (Insertion) – Inserting an element at the end of the list called rear end.
2. Dequeue (Deletion) – Deleting an element at the start of the list called the front end.
ENQUEUE (INSERTION)
ALGORITHM:
1. Inserts an element to the rear end of the queue
2. If Q is empty, the new node will be inserted at rear.
3. Otherwise a rear pointer will be assigned to the last node in Q and the new node will be inserted to
rear. Routine to enqueue an element in a Queue
Before after insert new node
newnode
Enqueue the element 30
Program:
void enqueue( int val)
{
struct node newnode;
newnode=(struct node *) malloc(sizeof(struct node))’;
newnode-data=val;
newnode->next=NULL;
if(front==NULL && rear ==NULL)
front=rear=newnode;
else
{
rear->next=newnode;
rear=newnode;
}
}
G.Vasukidevi 20
DEQUEUE (DELETION)
ALGORITHM:
1. deletes an element from the front end of the queue
2. If Q->next ==NULL then display Queue empty.
3. Otherwise assign the next node after the header node as front and delete that node.
10 20
Q
20
Q
FRONT REAR
Routine to dequeue an element from Queue
void deque(Queue Q)
{
struct node *t;
if (front==NULL && rear==NULL)
cout<<“Queue is empty”<<endl;
else
{
t=front;
front=front->next;
if(front==NULL)
rear=NULL;
free(t);
}
}
G.Vasukidevi 21
Display all node
void display()
{
if(front==NULL && rear==NULL)
cout<<Queue is underflow or empty;
else
{
for(t=front;t!=NULL;t=t->next)
cout<<t->data;
}
}
Peek
int peek()
{
if(front!=NULL)
return front->data;
else
return -1;
}
PRIORITY QUEUE
Priority queue are special kind of queue, where each element has a priority associated with it.
G.Vasukidevi 22
Array based implementation of Priority Queue
Operations
1. Enqueue
2. Deletemin
Enqueue
Empty Queue
-1 0 1 2 3 4
n=5
FRONT REAR
5
n=5
2 5
n=5
FRONT REAR
2 4 5
n=5
FRONT REAR
Deletemin
void deletemin()
{
if(rear==-1 || front==-1)
cout<<“Queue underflow”<<endl;
else if (front==rear)
{
cout<<“The deleted element is ”<<q[front];
front=rear=-1;
}
else
{
cout<<“The deleted element is ”<<q[front];
front++;
}
}
2. Deletemin
void delmin()
{
if(front==NULL)
cout<<”Queue is empty”;
else
{
t=front;
front=front->next;
free(t);
}
}
G.Vasukidevi 25
Applications of Priority Queue:
• Prim's algorithm
• Dijkstra's shortest path algorithm
• A* Search algorithm
• Priority queues are used to sort heaps
• Operating system for load balancing and interrupt handling.
• Priority queues are used in Huffman codes for data compression.
• In traffic lights, depending upon the traffic, the colors will be given priority.
Binary Heap
• Binary heap is a complete Binary tree in which the value present at any node is greater than all its children.
• A Binary Heap is a complete Binary Tree that is used to store data efficiently to get the max or min
element based on its structure.
• A Binary Heap is either Min Heap or Max Heap. In a Min Binary Heap, the value at the root must be
minimum among all keys present in Binary Heap.
• Binary heap is used for implementing priority queues.
G.Vasukidevi 26