Unit-V Trees & Graphs
Unit-V Trees & Graphs
STACK
Stack is a Linear Data Structure that follows Last In First Out(LIFO) principle.
Insertion and deletion can be done at only one end of the stack called TOP of the stack.
Example: - Pile of coins, stack of trays
STACK ADT:
STACK MODEL
TOP pointer
Two fundamental operations performed on the stack are PUSH and POP.
(a) PUSH:
1. Stack Overflow
An Attempt to insert an element X when the stack is Full, is said to be stack
overflow.
For every Push operation, we need to check this condition.
2. Stack Underflow:
return(1);
int TopElement(Stack S)
{
if(Top==-1)
{
Error(“Empty stack!!No
elements”); return 0;
}
else
return S[Top];
}
#include<stdio.h>
#include<conio.h>
#define size 5
int stack [ size ];
int top;
void push( )
{
int n ;
printf( "\n Enter item in stack" ) ;
scanf( " %d " , &n ) ;
if( top = = size - 1)
{
top = top + 1 ;
stack [ top ] = n ;
}
}
void pop( )
{
int item;
if( top = = - 1)
{
S
Header
30 20 10 NULL
40
newnode
Before Insertion
Push routine /*Inserts element at front of the list
void push(int X, Stack S)
{
Position newnode, Top;
newnode = malloc (sizeof( struct node ) );
newnode -> data = X;
newnode -> next = S -> next;
S -> next = newnode;
Top = newnode;
}
Header
40 30 20 10 NULL
After Insertion
TO
P
(iii) Pop Operation
It is the process of deleting the Top element of the stack.
With Linked List implementations, the element at the Front of the
List (i.e.) S -> next is always deleted.
It takes only one parameter. Pop(X).The element X to be deleted from the Front of
the List.
Before deleting the front element in the list, check for Empty Stack.
If the Stack is Empty, deletion is not possible.
Otherwise, make the front element in the list as “temp”.
Update the next field of header.
Using free ( ) function, Deallocate the memory allocated for temp node.
PANIMALAR
S www.padeepz.net
Heade
r
40 30
20 10 NULL
TOP
Before Deletion
Pop routine /*Deletes the element at front of list
void Pop( Stack S )
{
Position temp, Top;
Top = S -> next;
if( S -> next = = NULL)
Error(“empty stack! Pop not possible”);
else
{
Temp = S -> next;
S -> next = temp -> next;
free(temp);
Top = S -> next;
}}
Heade
r
40 30 20 10 NULL
HEAD
ER
30 20 10 NULL
A
fter Deletion
(iv) Return Top Element
Pop routine deletes the Front element in the List.
If the user needs to know the last element inserted into the stack, then the user
can return the Top element of the stack.
To do this, first check for Empty Stack.
If the stack is empty, then there is no element in the stack.
Otherwise, return the element present in the S -> next -> data in the List.
if(S->next==NULL)
error(“Stack is empty”);
return 0;
else
return S->next->data;
Heade
r
40 30 20 10 NULL
TOP
Implementation of stack using 'Linked List'
case 4:
display();
break;
case 5:
exit(0);
}
}while(op<5);
getch();
}
void create()
{
int n,i;
s=NULL;
printf("Enter the no of nodes to be created\n");
scanf("%d",&n);
newnode=(struct node*)malloc(sizeof(struct node));
printf("Enter the data\t");
scanf("%d",&newnode->data);
newnode->next=NULL;
top=newnode;
s=newnode;
for(i=2;i<=n;i++)
{
newnode=(struct node*)malloc(sizeof(struct node));
printf("Enter the data\t");
scanf("%d",&newnode->data);
newnode->next=top;
s=newnode;
top=newnode;
}}
void display()
{ top=s; while(top!
=NULL)
{
printf("%d->",top->data);
top=top->next;
}
printf("NULL\n");
}
void push()
{ top=s;
newnode=(struct node*)malloc(sizeof(struct node));
printf("Enter the data\t");
scanf("%d",&newnode->data);
newnode->next=top;
top=newnode;
s=newnode;
display();
}
void pop()
{
top=s;
if(top==NULL)
printf("Empty stack\n\n");
else
{
temp=top;
printf("Deleted element is \t %d\n\n",top-
>data); s=top->next;
free(temp);
display();
}}
Output
### Linked List Implementation of STACK Operations ###
Press 1-create
2-Push
3-Pop
4-Display
5-Exit
Your option ? 1
Enter the no of nodes to be created5
Enter the data 10
Enter the data20
Enter the data30
Enter the data40
Enter the data50
### Linked List Implementation of STACK Operations ###
Press 1-create
2-Push
3-Pop
4-Display
5-Exit
Your option ? 4
50->40->30->20->10->NULL
### Linked List Implementation of STACK Operations ###
Press 1-create
2-Push
3-Pop
4-Display
5-Exit
Your option ?2
Enter the data60
Your option ? 4
60->50->40->30->20->10->NULL
Your option ?2
Enter the data70
Your option ? 4
70->60->50->40->30->20->10->NULL
Your option ?3
Deleted element is70
Your option ? 4
50->40->30->20->10->NULL
Applications of Stack
INFIX:
The arithmetic operator appears between the two operands to which it is being
applied.
POSTFIX:
The arithmetic operator appears directly after the two operands to which it applies.
Also called reverse polish notation.
PREFIX:
The arithmetic operator is placed before the two operands to which it applies. Also
called polish notation.
Read the infix expression one character at a time until it encounters the delimiter “#”
Step 2: If the character is an operator, push it onto the stack. If the stack operator has a higher or
equal priority than input operator then pop that operator from the stack and place it onto the
output.
Step 3:If the character is left parenthesis, push it onto the stack
Step 4:If the character is a right parenthesis, pop all the operators from the stack till it encounters
left parenthesis, discard both the parenthesis in the output.
E.g. Consider the following Infix expression: - A*B+(C-D/E)#
A A
*
A
B
+ AB
*
+ AB*
( AB*
(
+
Read char Stack Output
C AB*C
(
+
- - AB*C
(
+
-
D AB*CD
(
+
/ / AB*CD
-
(
+
E / AB*CDE
-
(
+
AB*CDE/-
) /
-
(
+
Read char Stack Output
AB*CDE/-+
Read the postfix expression one character at a time until it encounters the delimiter „#‟
Step 1: If the character is an operand, push its associated value onto the stack.
Step 2: If the character is an operator, POP two values from the stack, apply the operator
to them and push the result onto the stack.
Operand Value
A 2
B 3
C 4
D 4
E 2
A 2
3
B
2
Char Read Stack
* 6
4
C 6
4
D 4
6
2
/ 4
6
2
- 6
+ 8
OUTPUT = 8
(
(
a a
(
+ a
+
(
b ab
+
(
) ab+
* ab+
c ab+c
ab+c*
/
d ab+c*d
ab+c*d/
+
21
e ab+c*d/e
/ ab+c*d/e
/
+
f ab+c*d/ef
/
+
# ab+c*d/ef/+
Operand Value
a 1
b 2
c 4
d 2
e 6
f 3
Char Read Stack
a 1
2
b
1
+ 3
4
c 3
* 12
2
d 12
/ 6
6
e 6
3
F 6
6
2
/ 6
+ 8
Output = 8
Infix to Postfix Conversion Output
#define SIZE 50 /* Size of Stack */
#include <ctype.h>
char s[SIZE];
int top=-1; /* Global declarations */
char pop()
{
return(s[top--]);
} (a+b)-(c-d)
Void main()
{ /* Main Program
*/ char infx[50],pofx[50],ch,elem;
int i=0,k=0;
printf("\nRead the Infix Expression ? ");
scanf("%s",infx);
push('#');
while( (ch=infx[i++]) != '\0')
{
if( ch == '(') push(ch);
else
if(isalnum(ch)) pofx[k++]=ch;
else
if( ch == ')')
{
while( s[top] != '(')
pofx[k++]=pop();
elem=pop(); /* Remove */
}
else
{ /* Operator */
while( pr(s[top]) >= pr(ch) )
pofx[k++]=pop();
push(ch);
}
}
while( s[top] != '#') /* Pop from
stack till empty
pofx[k++]=pop();
pofx[k]='\0'; /* Make pofx as
valid string */
printf("\n\nGiven Infix Expn: %s Postfix
Expn: %s\n",infx,pofx);
}
Towers of Hanoi
Towers of Hanoi can be easily implemented using recursion. Objective of the problem is
moving a collection of N disks of decreasing size from one pillar to another pillar. The
movement of the disk is restricted by the following rules.
Rule 2 : No larger disk could ever reside on a pillar on top of a smaller disk.
Rule 3 : A 3rd pillar could be used as an intermediate to store one or more disks, while they
A B C
Step 2. If N = 2, move the 1st disk from A to B. Then move the 2nd disk from A to C, The move
the 1st disk from B to C.
Step 3. If N = 3, Repeat the step (2) to more the first 2 disks from A to B using C as
intermediate. Then the 3rd disk is moved from A to C. Then repeat the step (2) to move 2 disks
from B to C using A as intermediate.
In general, to move N disks. Apply the recursive technique to move N - 1 disks from A to B
using C as an intermediate. Then move the N th disk from A to C. Then again apply the recursive
technique to move N - 1 disks from B to C using A as an intermediate
Since disks are moved from each tower in a LIFO manner, each tower may be considered
as a Stack. Least Number of moves required solving the problem according to our algorithm is
given by,
O(N)=O(N-1)+1+O(N-1) =2N-1
Function Calls
When a call is made to a new function all the variables local to the calling routine need to
be saved, otherwise the new function will overwrite the calling routine variables. Similarly the
current location address in the routine must be saved so that the new function knows where to go
after it is completed.
Call
balance()
Call
push()
Recursive Function to Find Factorial
int fact(int n)
{
int S;
if(n==1)
return(1);
else
S = n * fact( n – 1 );
return(S)
}
Compilers check the programs for errors, a lack of one symbol will cause an error.
A Program that checks whether everything is balanced.
Every right parenthesis should have its left parenthesis.
Check for balancing the parenthesis brackets braces and ignore any other character.
((B*B)-{4*A*C}/[2*A]) #
( (
(
)
(
{ {
(
}
(
[ [
(
]
(
Empty stack, hence the symbols the balanced in the given expression.
Example for unbalanced symbols:
QUEUES:
Queue is a Linear Data Structure that follows First in First out (FIFO) principle.
Insertion of element is done at one end of the Queue called “Rear “end of the Queue.
Deletion of element is done at other end of the Queue called “Front “end of the Queue.
Example: - Waiting line in the ticket counter.
Front End
RearEnd
QUEUE Q
Deletion
Insertion
Queue Model
Front Pointer:-
Rear Pointer:-
Front (F) = - 1
Rear (R) = - 1
Operations on Queue
1. EnQueue
2. DeQueue
(i) EnQueue operation:-
It is the process of inserting a new element at the rear end of the Queue.
For every EnQueue operation
o Check for Full Queue
o If the Queue is full, Insertion is not possible.
o Otherwise, increment the rear end by 1 and then insert the element in the rear end
of the Queue.
It is the process of deleting the element from the front end of the queue.
For every DeQueue operation
o Check for Empty queue
o If the Queue is Empty, Deletion is not possible.
o Otherwise, delete the first element inserted into the queue and then increment the
front by 1.
Queue Overflow
Queue Underflow
An Attempt to insert an element X at the Rear end of the Queue when the
Queue is full is said to be Queue overflow.
For every Enqueue operation, we need to check this condition.
(ii) Queue Underflow:
An Attempt to delete an element from the Front end of the Queue when the
Queue is empty is said to be Queue underflow.
For every DeQueue operation, we need to check this condition.
Implementation of Queue
return ( 1 );
As we keep inserting the new elements at the Rear end of the Queue, the Queue becomes
full.
When the Queue is Full, Rear reaches its maximum Arraysize.
For every Enqueue Operation, we need to check for full Queue condition.
if ( Rear = = ArraySize - 1 )
return ( 1 );
}
(iii) Enqueue Operation
It is the process of inserting a new element at the Rear end of the Queue.
It takes two parameters, Enqueue(X, Q). The elements X to be inserted at the Rear end of
the Queue Q.
Before inserting a new Element into the Queue, check for Full
Queue. If the Queue is already Full, Insertion is not possible.
Otherwise, Increment the Rear pointer by 1 and then insert the element X at the Rear end
of the Queue.
If the Queue is Empty, Increment both Front and Rear pointer by 1 and then insert the
element X at the Rear end of the Queue.
#include<stdio.h>
#include<conio.h>
#define SIZE 5
int front = - 1;
int rear = - 1;
int q[SIZE];
void insert( );
void del( );
void display( );
void main( )
{
int choice;
clrscr( );
do
{
printf("\t Menu");
printf("\n 1. Insert");
printf("\n 2. Delete");
printf("\n 3. Display ");
printf("\n 4. Exit");
void del( )
{
if(front = = - 1)
{
Front = - 1;
Rear = - 1;
}
else
{
Front = front + 1;
}}
void display(
)
{
int i;
if( front = = - 1)
{
printf("\nQueue is empty... ");
return;
}
for(i = front; i<=rear; i++)
printf("\t%d",q[i]);}
Linked List Implementation of Queue
Heade
r
10 20 30 40 NULL
Front Rear
struct node;
typedef struct node * Queue;
typedef struct node * position;
int IsEmpty (Queue Q);
Queue CreateQueue (void);
void MakeEmpty (Queue Q);
void Enqueue (int X, Queue Q);
void Dequeue (Queue Q);
struct node
{
int data ;
position next;
}* Front = NULL, *Rear = NULL;
(i) Queue Empty Operation:
Initially Queue is Empty.
With Linked List implementation, Empty Queue is represented as S -> next = NULL.
It is necessary to check for Empty Queue before deleting the front element in the Queue.
Empty Queue
(ii) EnQueue Operation
It is the process of inserting a new element at the Rear end of the Queue.
It takes two parameters, EnQueue ( int X , Queue Q ). The elements X to be inserted
into the Queue Q.
Using malloc ( ) function allocate memory for the newnode to be inserted into the Queue.
If the Queue is Empty, the newnode to be inserted will become first and last node in the
list. Hence Front and Rear points to the newnode.
Otherwise insert the newnode in the Rear -> next and update the Rear pointer.
Heade NULL
r Q
Before Insertion
Front Rear
(iii) DeQueue Operation After Insertion
Heade
r
20 30 40 NULL
Front Rear
struct node
{
int data;
position next;
};
void main()
{
int choice;
clrscr();
do
{
printf("1.Enqueue\n2.Dequeue\n3.display\n4.exit\n");
printf("Enter your choice\n\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
enqueue();
break;
case 2:
dequeue();
break;
case 3:
display();
break;
case 4:
exit(0);
}
}
while(choice<5);
}
void enqueue()
{
newnode=(struct node*)malloc(sizeof(struct
node)); printf("\n Enter the data to be enqueued\n");
scanf("%d",&newnode->data);
newnode->next=NULL;
if(rear==NULL)
front=rear=newnode;
else {
rear->next=newnode;
rear=newnode;
}
display();
}
void dequeue()
{
if(front==NULL)
printf("\nEmpty queue!!!!! Deletion not possible\n");
else if(front==rear)
{
printf("\nFront element %d is deleted from queue!!!! now queue is
empty!!!! no more deletion possible!!!!\n",front->data);
front=rear=NULL;
}
else
{
temp=front;
front=front->next;
printf("\nFront element %d is deleted from queue!!!!\n",temp->data);
free(temp);
}
display();
}
void display()
{
p=front; while(p!
=NULL)
{
printf("%d -> ",p-
>data); p=p->next;
}
printf("Null\n");
}
Output
Applications of Queue
1. Serving requests on a single shared resource, like a printer, CPU task scheduling etc.
2. In real life, Call Center phone systems will use Queues, to hold people calling them in
an order, until a service representative is free.
3. Handling of interrupts in real-time systems. The interrupts are handled in the same order
as they arrive, First come first served.
4. Batch processing in operating system.
5. Job scheduling Algorithms like Round Robin Algorithm uses Queue.
With the array implementation of Queue, the element can be deleted logically only by
moving Front = Front + 1.
Here the Queue space is not utilized fully.
In Circular Queue, the insertion of a new element is performed at the very first location of the
queue if the last location of the queue is full, in which the first element comes just after the last
element.
A circular queue is an abstract data type that contains a collection of data which allows
addition of data at the end of the queue and removal of data at the beginning of the
queue.
Circular queues have a fixed size.
Circular queue follows FIFO principle.
Queue items are added at the rear end and the items are deleted at front end of the circular
queue
Here the Queue space is utilized fully by inserting the element at the Front end if the
rear end is full.
ArraySize
It is same as Linear Queue EnQueue Operation (i.e) Inserting the element at the Rear end.
First check for full Queue.
If the circular queue is full, then insertion is not possible.
Otherwise check for the rear end.
If the Rear end is full, the elements start getting inserted from the Front end.
F
Circular Queue DeQueue Operation
It is same as Linear Queue DeQueue operation (i.e) deleting the front element.
First check for Empty Queue.
If the Circular Queue is empty, then deletion is not possible.
If the Circular Queue has only one element, then the element is deleted and Front and Rear
pointer is initialized to - 1 to represent Empty Queue.
Otherwise, Front element is deleted and the Front pointer is made to point to next element in the
Circular Queue.
F, R
F= -1,R= --1
void insert()
{
int x;
if((front==0&&rear==max-1)||(front>0&&rear==front-1))
printf("Queue is overflow\n");
else
{
printf("Enter element to be insert:");
scanf("%d",&x);
if(rear==max-1&&front>0)
{ rear=0;
q[rear]=x;
}
else
{
if((front==0&&rear==-1)||(rear!=front-1)) q[+
+rear]=x;
} }}
void delet()
{
int a;
if((front==0)&&(rear==-1))
printf("Queue is underflow\n");
if(front==rear)
{
a=q[front];
rear=-1;
front=0;
}
else if(front==max-1)
{
a=q[front];
front=0;
}
else
a=q[front++];
printf("Deleted element is:%d\n",a);
}
void display()
{
int i,j; if(front==0&&rear==-1)
printf("Queue is underflow\n");
if(front>rear) {
for(i=0;i<=rear;i++) printf("\t
%d",q[i]); for(j=front;j<=max-
1;j++) printf("\t%d",q[j]);
printf("\nrear is at %d\n",q[rear]);
printf("\nfront is at %d\n",q[front]); }
else
{
for(i=front;i<=rear;i++) printf("\t
%d",q[i]); printf("\nrear
is at %d\n",q[rear]); printf("\nfront
is at %d\n",q[front]);
}
printf("\n");
}
OUTPUT
In DEQUE, insertion and deletion operations are performed at both ends of the Queue.
Insertion
Deletion
Deletion
Front Rear
(ii) Output Restricted DEQUE
Here insertion is allowed at both ends and deletion is allowed at one end.
Insertion
Insertion
Deletion
Front Rear
Operations on DEQUE
Four cases for inserting and deleting the elements in DEQUE are
}
www.padeepz.n
et