UNIT-2
STACK
1-Abstract Data Type 7-Removal of recursion Problem
solving using iteration and
2- Primitive Stack operations: Push recursion with examples such as
& Pop, binary search,
3-Array and Linked 8-Fibonacci numbers, and Hanoi
Implementation of Stack in C, towers.
4-Application of stack: Prefix and 9-Tradeoffs between iteration and
Postfix Expressions, Evaluation of recursion.
postfix expression,
5- Iteration and Recursion-
Principles of recursion,
6-Tail recursion,
STACK
• A stack is a linear data structure, collection of items of the same type.
• Stack follows the Last In First Out (LIFO) fashion wherein the last
element entered is the first one to be popped out.
• In stacks, the insertion and deletion of elements happen only at one
end point of it. Which is known as top of stack.
• A stack is an Abstract Data Type (ADT), commonly used in most
programming languages. It is named stack as it behaves like a
real-world stack, for example – a deck of cards or a pile of plates, etc.
Operations performed on Stack
1) Push (): This function adds an element to the top of the Stack.
2) Pop (): This function removes the topmost element from the stack.
3) IsEmpty(): Checks whether the stack is empty.
4) IsFull (): Checks whether the stack is full.
5) Peek (): get the top data element of the stack, without removing it.
int peek() bool IsFull()
{ { if (top==maxsize)
return stack[top]; return true;
} else return false;
}
How Stack Work
1- Initially, we set a pointer Peek/Top to keep the track of the topmost
item in the stack.
2- Initialize the stack to -1. Then, we check whether the stack is empty
through the comparison of Peek to -1 i.e. Top == -1
3- As we add the elements to the stack, the position of the Peek
element keeps updating every time.
4- As soon as we pop or delete an item from the set of inputs, the
top-most element gets deleted and thus the value of Peek/Top gets
reduced.
Implementation of operations in stack
1- If top== -1 --🡪 Stack is empty (under flow condition)
2- If Top == max-1 ---------🡪 Stack is full. [ when we insert an element
we check this condition. ( Overflow condition)
Algorithm and C function to insert an
element void Push()
{
Push(Stacktop,size,x) int x;
if(Top==Size-1)
Here we insert an element x into {
stack, where size is the size of stack printf("\nOverflow!!");
and we have to insert an element }
using Top.
else
1- if top= size-1 then write stak is {
empty or Overflow and go to step 4 printf("\nEnter element to be inserted to the stack:");
2- set Top= Top+1 scanf("%d",&x);
Top=Top+1;
3- set x into array of stack or
Stack(Top)= x stack_array[Top]=x;
}
4- exit }
Algorithm and C function to delete an element
Pop( Stack, Top, X) void Pop()
We have to define this…….. {
if(Top==-1)
1- if top= -1 then write stack is empty {
and go to step 4 printf("\nUnderflow!!");
2- set x= stack[top] }
3- set top=top-1 else
4- stop {
printf("\ndeleted element:
%d",stack_array[Top]);
Top=Top-1;
}
}
#define Size 4 void Push()
int Top=-1, stack_array[Size]; { int x;
void Push(); if(Top==Size-1)
void Pop(); { printf("\nOverflow!!");
void show(); }
int main() else
{ { printf("\nEnter element to be inserted to the stack:");
int choice; scanf("%d",&x);
while(1) Top=Top+1;
{ stack_array[Top]=x;
printf("\nOperations performed by Stack"); }
printf("\[Link] the element\[Link] the }
element\[Link]\[Link]"); void Pop()
printf("\n\nEnter the choice:"); { if(Top==-1)
scanf("%d",&choice); switch(choice) { printf("\nUnderflow!!");
{ }
case 1: Push(); break; else
case 2: Pop(); break; { printf("\nPopped element: %d",stack_array[Top]);
case 3: show(); reak; Top=Top-1;
case 4: exit(0); }
default: printf("\nInvalid choice!!"); }
}
}
Operations performed by Stack
void show()
[Link] the element
{
[Link] the element
if(Top==-1)
[Link]
{
[Link]
printf("\nUnderflow!!");
}
Enter the choice:2
else
Popped element: 10
{
printf("\nElements present in the stack:
\n"); Operations performed by Stack
for(int i=Top;i>=0;--i) [Link] the element
printf("%d\n",stack_array[i]); [Link] the element
} [Link]
} [Link]
Enter the choice:3
Underflow!!
Time Complexity of Stack Operations
----🡪 only a single element can be accessed at a time in Stacks.
While performing push() and pop() operations on the stack,
it takes-------------------------- O(1) time.
Applications of Stack
-🡪 The Stack is used to solve a few of the general problems like:
1- Tower of Hanoi
2-N queens problem
3- Infix to prefix conversion, etc.
Applictions
The way to write arithmetic expression is known as a notation. An
arithmetic expression can be written in three different but equivalent
notations, i.e., without changing the essence or output of an
expression. These notations are −
1- Infix Notation 2- Prefix (Polish) Notation 3- Postfix
(Reverse-Polish) Notation
[Link]. 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+∗
Expressions: Convert in to postfix
1- A + (B* C – ( D/E^F)*G)*H
2- ((A+B)*D)^(E-F)
3- A+((B+C) + (D+E)*F)/G
4- A-B/(C*D^F)
5- (A-B/C) * (D*E-F)
6- A/B^C-D
SNO SYMBOL STACK EXPRESSION
(A+(B*C)/D) 1 ( ( ----------
2 A ( A
3 + (+ A
4 ( (+( A
5 B (+( AB
6 * (+(* AB
7 C (+(* ABC
8 ) (+ ABC*
9 / (+/ ABC*
10 D (+/ ABC*D
11 ) ------- ABC*D/+
SNO SYMBOL STACK EXPRESSION
B* C – ( D/E^F)*G)*H)
1 ( ( ---------------------
2 A ( A
3 + (+ A
4 ( (+( A
5 B (+( AB
6 * (+(* AB
7 C (+(* ABC
8 - (+(- ABC*
9 ( (+(-( ABC*
10 D (+(-( ABC*D
11 / (+(-(/ ABC*D
12 E (+(-(/ ABC*DE
13 ^ (+(-(/^ ABC*DE
14 F (+(-(/^ ABC*DEF
Algorithm of Evaluation of a post fix
expression
1- Add a right parenthesis “)” at the end of P.
2- Scan p From left to right and repeat step 3 and 4 for each element of
P until “)” is uncounted.
3- if an operands is occur,, put is into Stack.
4- if an operator occur then
4.1 remove the top two element from P (A and B)
4.2 Evaluate B*A
4.3 Place the result of 4.2 into stack
5- set value equal to the top element on stack
6- exit
Solve the following postfix expression
P: 5 6 2 + * 12 4 / -
SYMBOL STACK
5 5
6 56
2 562
+ 58
* 40
12 40 12
4 40 12 4
/ 40 3
- 37
Solve the following postfix expression
P: 12 7 3 - / 2 1 5 + * +
SYMBOL STACK
12 12
7 12 7
3 12 7 3
- 12 4
/ 3
2 3 2
1 3 2 1
5 3 2 1 5
+ 3 2 6
* 3 12
+ 15
Difference between Recursion and Iteration
SNO On the Recursion Iteration
basis of
1 Basic Recursion is the process of calling a In iteration, there is a repeated execution of the set of
function itself within its own code. instructions. In Iteration, loops are used to execute the
set of instructions repetitively until the condition is false.
2 Syntax There is a termination condition is The format of iteration includes initialization, condition,
specified. and increment/decrement of a variable.
3 Termination The termination condition is defined Here, the termination condition is defined in the
within the recursive function. definition of the loop.
4 Applied It is always applied to functions. It is applied to loops.
5 Speed It is slower than iteration. It is faster than recursion.
6 Memory It uses more memory as It uses les
compared to iteration.
7 Code size The code size in recursion is The code size in iteration is larger than the code
smaller than the code size in size in recursion.
iteration.
Recursion Iteration
// method to find factorial of given // Method to find the factorial of a given
number number
int factorialUsingIteration(int n)
int factorialUsingRecursion(int n)
{
{
int res = 1, i;
if (n == 0)
return 1; // using iteration
for (i = 2; i <= n; i++)
// recursion call res *= i;
return n * factorialUsingRecursion(n - 1);
return res;
}
}
int main()
{
int num = 5;
printf(“%d Factorial of a number using Recursion is: " ,
factorialUsingRecursion(5);
printf(“%d Factorial of a number using Recursion is: " ,
factorialUsingIteration(5);
return 0;
}
Types of recursion
1- Direct Recursion--- When a function calls itself within the same
function repeatedly, it is called the direct recursion.
2- Indirect Recursion
3- Tail Recursion
4- No Tail/ Head Recursion
5- Linear recursion
6- Tree Recursion
Types of recursion
1- Direct Recursion--- When a function calls itself within the same
function repeatedly, it is called the direct recursion.
2- Indirect Recursion
3- Tail Recursion
4- No Tail/ Head Recursion
5- Linear recursion
6- Tree Recursion
Types of recursion
1- Direct Recursion--- When a function calls itself within the same function repeatedly, it is
called the direct recursion.
fun ( )
{
fun( );
}
Ex Fibonacci series
2- Indirect Recursion- When a function is mutually called by another function in a circular
manner, the function is called an indirect recursion function.
fun1 ( )
{
fun2( );
}
fun2 ( )
{
fun1( );
}
3- Tail Recursion-- A recursive function is called the tail-recursive if the function makes recursive calling itself, and that
recursive call is the last statement executes by the function. After that, there is no function or statement is left to call
the recursive function.
#include <stdio.h>
// function definition
void fun1(int num)
{
if (num == 0)
return ;
else
printf ("\n Number is: %d", num); // print the number
return fun1 (num - 1); // recursive call at the end in the fun() function
}
int main ()
{
fun1(10); // pass 10 as integer argument
return 0;
}
Fibonacci
#include<stdio.h>
Series int main ()
int fibo_num (int i) {
{ int i;
// if the num i is equal to 0, return 0; // use for loop to get the first 10 fibonacci series
if ( i == 0) for ( i = 0; i < 10; i++)
{ {
return 0; printf (" %d \t ", fibo_num (i));
} }
if ( i == 1) return 0;
{ }
return 1;
}
return fibo_num (i - 1) + fibo_num (i -2);
}
Tower Of Hanoi
• The tower of Hanoi is a mathematical puzzle. It consists of three rods
and a number of disks of different sizes which can slide to any rod.
The puzzle starts with the disks in a neat stack in ascending order of
size on one rod, the smallest at the top. We have to obtain the same
stack on the third rod.
• The objective of the puzzle is to move the entire stack to another rod,
obeying the following simple rules−
• Only one disk can be moved at a time.
• Each move consists of taking the upper disk from one of the stacks
and placing it on top of another stack i.e. a disk can only be moved if
it is the uppermost disk on a stack.
#include<stdio.h>
void TOH(int n,char x,char y,char z)
{
if(n>0) {
TOH(n-1,x,z,y);
printf("\n%c to %c",x,y);
TOH(n-1,z,y,x);
}
}
int main()
{
int n;
printf("enter the value of n");
scanf("%d",&n);
TOH(n,'A','B','C');
}
Linear Search
• Linear Search is defined as a sequential search algorithm that starts at
one end and goes through each element of a list until the desired
element is found, otherwise the search continues till the end of the
data set. It is the easiest searching algorithm
Binary Search
• The basic steps to perform Binary Search are:
• Begin with the mid element of the whole array as a search key.
• If the value of the search key is equal to the item then return an index
of the search key.
• Or if the value of the search key is less than the item in the middle of
the interval, narrow the interval to the lower half.
• Otherwise, narrow it to the upper half.
• Repeatedly check from the second point until the value is found or
the interval is empty.
• Binary Search Algorithm can be implemented in the following two ways
1- Iterative Method 2- Recursive Method
binarySearch(arr, x, low, high)
repeat till low = high
• mid = (low + high)/2
• if (x == arr[mid])
• return mid
•
• else if (x > arr[mid]) // x is on the right side
• low = mid + 1
•
• else // x is on the left side
• high = mid - 1
2- Recursive Method
binarySearch(arr, x, low, high)
if low > high
return False
else
mid = (low + high) / 2
if x == arr[mid]
return mid
else if x > arr[mid] // x is on the right side
return binarySearch(arr, x, mid + 1, high)
else // x is on the right side
return binarySearch(arr, x, low, mid - 1)
QUEUE
What is Queue?
• A queue is defined as a linear data structure that is open at both ends and the
operations are performed in First In First Out (FIFO) order.
• We define a queue to be a list in which all additions to the list are made at one
end, --- from REAR i.e Enqueue
• and all deletions from the list are made at the other end. --from REAR i.e
Enqueue
• The element which is first pushed into the order, the operation is first performed
on that
FIFO Principle of Queue:
• A Queue is like a line waiting to purchase tickets, where the first
person in line is the first person served. (i.e. First come first serve).
• Position of the entry in a queue ready to be served, that is, the first
entry that will be removed from the queue, is called the front of the
queue(sometimes, head of the queue),
• similarly, the position of the last entry in the queue, that is, the one
most recently added, is called the rear (or the tail) of the queue. See
the below figure.
Ex- 0 1 2 3 4 5
Hear Rear=-1 and front =-1
Queue is empty
1- Insert element in queue i.e --- A
0 1 2 3 4 5
A
Now Rear = 0 and front =0 [ when we insert first element both rear
and front are changed]
2- Insert element in queue i.e --- B
0 1 2 3 4 5
A B
Now Rear = 1 and front =0 [increase only rear ]
3-Insert element in queue i.e--- C D E F
0 1 2 3 4 5
A B C D E F
Now Rear = 5 (Max size of queue) and front =0
Now We can’t insert element in queue because queue is full----------- Rear= maxsize-1
If(Rear=maxsize-1) QUEUE ID OVERFLOW
Characteristics of Queue:
1- Queue can handle multiple data.
2- We can access both ends.
3- They are fast and flexible.
Queue Representation:
• Like stacks, Queues can also be represented in an array: In this
representation, the Queue is implemented using the array. Variables
used in this case are
• Queue: the name of the array storing queue elements.
• Front: the index where the first element is delete in the array
representing the queue.
• Rear: the index where the last element is stored in an array
representing the queue.
Types of queue
1- Simple Queue or Linear Queue
2- Circular Queue
3- Priority Queue
4- Double Ended Queue (or Deque)
Simple Queue or Linear Queue
• The major drawback of using a linear Queue is that insertion is done
only from the rear end.
• If the first three elements are deleted from the Queue, we cannot
insert more elements even though the space is available in a Linear
Queue. In this case, the linear Queue shows the overflow condition as
the rear is pointing to the last element of the Queue.
• Ex- 0 1 2 3 4 5 6
D E F G
F R
Front= 3 and rear = 6(max-1)---------- Queue if Full
Operations performed on queue
The fundamental operations that can be performed on queue are listed as
follows -
• Enqueue: The Enqueue operation is used to insert the element at the
rear end of the queue. It returns void.
• Dequeue: It performs the deletion from the front-end of the queue. It
also returns the element which has been removed from the front-end. It
returns an integer value.
• Peek: This is the third operation that returns the element, which is
pointed by the front pointer in the queue but does not delete it.
• Queue overflow (isfull): It shows the overflow condition when the queue
is completely full.
• Queue underflow (isempty): It shows the underflow condition when the
Queue is empty, i.e., no elements are in the Queue.
Queue C Function
Enqueue insert an element– Algo. void insert()
{
Insert(queue,max front,rear,item)
int item;
1- if rear= max-1 if(rear == MAX - 1)
then write queue if overflow and exit printf("Queue Overflow n");
2- if rear= -1 then set rear=0 else
{
else rear = rear+1 if(front== - 1)
3- queue[rear]=item front = 0;
4- stop printf("Inset the element in queue : ");
scanf("%d", &item);
rear = rear + 1;
queue_array[rear] = item;
}
}
Queue C Function
Dequeue delete an element– Algo. void delete()
delete(queue,max front,rear,item) {
if(front == - 1 )
1- if Front=-1 or front >rear
{
then write queue if underflow and printf("Queue Underflow n");
exit
return;
2- item=queue[front] }
3- if front= rear[ it means that queue else
has only one element {
else front=front+1 printf("Element deleted from queue is :
4- stop %dn", queue[front]);
front = front + 1;
}
}
Queue C Function
Display– Algo. void display()
display(queue, front, rear) {
1- if Front=-1 or front >rear int i;
if(front == - 1)
then write queue queue is empty and
exit printf("Queue is empty n");
2- Repeate step 3 while front<=rear else
{
3- print value of queue[i]
printf("Queue is : n");
4- stop
for(i = front; i <= rear; i++)
printf("%d ", queue_array[i]);
printf("n");
}
}
Application of queue
• A queue is used in scheduling processes in a CPU.
• It is used in data transfer between processes.
• It holds multiple jobs which are then called when needed.
• DFS
• Spooling
Advantages of queue:--
. Shows in previous slide
Disadvantage of queue:-
Circular Queue
• In Circular Queue, all the nodes are represented as circular. It is similar to
the linear Queue except that the last element of the queue is connected
to the first element. It is also known as Ring Buffer, as all the ends are
connected to another end. The representation of circular queue is shown
in the below image –
• The drawback that occurs in a linear queue is overcome by using the
circular queue. If the empty space is available in a circular queue, the
new element can be added in an empty space by simply incrementing the
value of rear. The main advantage of using the circular queue is better
memory utilization.
• Circular queue explanation:-
Circular Queue C Function
Enqueue insert an element– Algo. Enqueue()
{
Insert(CQ,max front,rear,item) int element;
1- If (front=0 and rear=max-1)or If ((rear+1)%N=front)
front=rear+1 then write Printf(“CQ is full”);
Else
CQ is overflow and exit {
2- if front=-1 then set front =0 and If(front = = -1)
rear=0 {
front=0; rear=0;
Else if rear=max-1 then set rear=0 }
Else rear=rear+1 rear=(rear+1)%N;
Printf(“enter element”);
3- insert item i.e CQ[rear]=item scanf(“%d\n”,&element);
4- stop CQ[raer]=element;
}
}
Circular Queue C Function
void deletion()
Dequeue insert an element– Algo. {
Delete(CQ,max front,rear,item) If (front == -1)
{
1- if front=-1 then write CQ is empty printf("Queue Underflown");
and exit return ;
}
2- set element = CQ[front] printf("Element deleted from queue is : %dn",cqueue_arr[front]);
3- if front=rear then front=-1 and if(front == rear)
{
rear=-1
front = -1;
else if front= max-1 then set front=0 rear=-1;
} else
Else front = front+1 { if(front == MAX-1)
4- stop front = 0;
else
front = front+1;
}
}
Priority Queue
• It is a special type of queue in which the elements are arranged based on the
priority. It is a special type of queue data structure in which every element has
a priority associated with it. Suppose some elements occur with the same
priority, they will be arranged according to the FIFO principle. The
representation of priority queue is shown in the below image –
• Insertion in priority queue takes place based on the arrival, while deletion in
the priority queue occurs based on the priority.
• Priority queue is mainly used to implement the CPU scheduling algorithms.
• There are two types of priority queue that are discussed as follows –
• Ascending priority queue - In ascending priority queue, elements can
be inserted in arbitrary order, but only smallest can be deleted first.
Suppose an array with elements 7, 5, and 3 in the same order, so,
insertion can be done with the same sequence, but the order of deleting
the elements is 3, 5, 7.
• Descending priority queue - In descending priority queue, elements
can be inserted in arbitrary order, but only the largest element can be
deleted first. Suppose an array with elements 7, 3, and 5 in the same
order, so, insertion can be done with the same sequence, but the order
of deleting the elements is 7, 5, 3.
Deque (or, Double Ended Queue)
• In Deque or Double Ended Queue, insertion and deletion can be done from
both ends of the queue either from the front or rear. It means that we can
insert and delete elements from both front and rear ends of the queue. .
Deque can be used as a palindrome checker means that if we read the string
from both ends, then the string would be the same.
• Deque can be used both as stack and queue as it allows the
insertion and deletion operations on both ends. Deque can be considered as
stack because stack follows the LIFO (Last In First Out) principle in which
insertion and deletion both can be performed only from one end. And in
deque, it is possible to perform both insertion and deletion from one end,
and Deque does not follow the FIFO principle.
• There are two types of deque that are discussed as follows -
1- Input restricted deque - As the name implies, in input restricted queue,
insertion operation can be performed at only one end, while deletion can be
performed from both ends.
2- Output restricted deque - As the name implies, in output restricted queue,
deletion operation can be performed at only one end, while insertion can be
performed from both ends.
1- Input restricted deque –
i- Insert an element at rear
ii- Delete an element from front
iii- Delete an element from rear
2- Output restricted deque -
i- Insert an element at rear
ii- Delete an element from front
iii- Insert an element from front
Insertion Deletion
Front side F= F-1 F=F+1
Rear side R = R+1 R=R-1
Deque representation
iii- Delete an element from rear
void delet()
{
if (rear==-1)
{
printf(“Dequeue is empty \n”);
else
item= Dq[Rear]
Printf(“\n The item %D is deleted”,item);
If (Front== Rear)
{ front=-1; rear=-1;
}
else if (Rear==0)
rear=max-1;
else rear=rear-1;
}
Insert from Front--
Void insert()
{
if ((f==0 && r==max-1)II (f=r+1) Dq[f]= item;
printf(“ \n\n Overflow\n”); Printf(“ Element inserted”);
else } }
if( f==-1)
{
r=0; f=0;
}
else if (f==0)
f=max-1;
else f=f-1;
Printf(Enter element to be inserted”);
scanf(“%d”, element);