Ds Whole
Ds Whole
Ds Whole
ALGORITHM:
a. Push:
1. Initialise the data of temp node with given data.
2. Assign the next of temp node with top.
3. Assign top with temp top.
b. Pop:
1. Check if stack is empty.
2. If yes return -1.
3. Else initialise temp node with top.
4. *top=*top->next;
5. Initialise data with temp->data.
6. Release temp from memory.
7. Return data.
CODE:
#include<iostream>
#include<stdlib.h>
struct node
{
int data;
};
return NULL;
return top==NULL;
temp->data=d;
temp->next=*top;
*top=temp;
int d;
if(Isempty(top))
return -1;
temp=*top;
*top=(*top)->next;
d=temp->data;
free(temp);
return d;
int main()
int d;
cin>>d;
while(d!=-1)
push(&top,d);
cin>>d;
while(!Isempty(top))
cout<<pop(&top)<<" ";
return 0;
OUTPUT:
DISCUSSION:
Every operation takes extra space and time to deal with references.
LEARNING:
I learnt that implementation of stack using linked list has extra space
complexity but it is done by dynamic memory allocation which
prevents any waste of memory whatsoever. I also learnt that all the
operations in this implementation take constant time.
PROGRAM 5
AIM: WAP to perform push and pop operations on a stack
implemented using array .
ALGORITHM:
a. Push operation
1. Check if stack is full.
2. If yes, print stack overflow.
3. Else increase top by 1 and store the value at top position.
b. Pop operation
1. Check if stack is empty.
2. if yes, print stack underflow.
3. Else remove element from the top of array and reduce top
by 1 .
CODE:
#include<iostream>
#include<stdlib.h>
struct arraystack
{
int top;
int capacity;
int *arr;
};
if(!s)
return NULL;
s->capacity=10;
s->top=-1;
s->arr=(int* )malloc((s->capacity*sizeof(int)));
return s;
};
return (s->top==s->capacity-1);
{
return (s->top==-1);
if(Isfull(s))
cout<<"Stack overflow\n";
else
s->arr[++s->top]=d;
if(Isempty(s))
cout<<"stack is empty\n";
else
return (s->arr[s->top--]);
int main()
{
int d;
cin>>d;
int i=1;
while(d!=-1&&i<=10)
push(s,d);
cin>>d;
i=1;
while(i<=11&&!Isempty(s))
cout<<pop(s)<<" ";
i++;
return 0;
}
OUTPUT:
DISCUSSION:
LEARNING OUTCOME:
THEORY:
is also an abstract data type or a linear data structure, in which the
first element is inserted from one end called the rear(also called tail),
and the removal of existing element takes place from the other end
called as front(also called head).
This makes queue as FIFO(First in First Out) data structure, which
means that element inserted first will be removed first.
The process to add an element into queue is called enqueue and the
process of removal of an element from queue is called dequeue.
ALGORITHM:
Enqueue Operation
CODE:
#include <iostream>
using namespace std;
int queue[100], n = 100, front = - 1, rear = - 1;
void Insert() {
int val;
if (rear == n - 1)
cout<<"Queue Overflow"<<endl;
else {
if (front == - 1)
front = 0;
cout<<"Insert the element in queue : "<<endl;
cin>>val;
rear++;
queue[rear] = val;
}
}
void Delete() {
if (front == - 1 || front > rear) {
cout<<"Queue Underflow ";
return ;
} else {
cout<<"Element deleted from queue is : "<< queue[front] <<endl;
front++;;
}
}
void Display() {
if (front == - 1)
cout<<"Queue is empty"<<endl;
else {
cout<<"Queue elements are : ";
for (int i = front; i <= rear; i++)
cout<<queue[i]<<" ";
cout<<endl;
}
}
int main() {
int ch;
cout<<"1) Insert element to queue"<<endl;
cout<<"2) Delete element from queue"<<endl;
cout<<"3) Display all the elements of queue"<<endl;
cout<<"4) Exit"<<endl;
do {
cout<<"Enter your choice : "<<endl;
cin<<ch;
switch (ch) {
case 1: Insert();
break;
case 2: Delete();
break;
case 3: Display();
break;
case 4: cout<<"Exit"<<endl;
break;
default: cout<<"Invalid choice"<<endl;
}
} while(ch!=4);
return 0;
}
OUTPUT:
DISCUSSION:
In queue, insertion and deletion happen at the opposite ends, so
implementation is not as simple as stack.
From the above program we can conclude that-
Time Complexity of Enqueue : O(1)
Time Complexity of Dequeue : O(n)
LEARNING OUTCOMES:
Students learned to create a Queue using Array. Students also learned
about the various functions like Enqueue(), Dequeue(), Front() and
Rear() that are used in queue.
PROGRAM 12
AIM: WAP to implement insertion, searching, deletion and traversal
algorithm on Binary search tree.
THEORY: In binary search tree all the left subtree elements should be
less than root data and all the right subtree elements should be
smaller than data. This is called binary search tree property. Note
that this property should be satisfied at every node in the tree.
Since root data is always between left subtree data and right subtree
data performing inorder traversal on binary search tree produces a
sorted list. If we are searching for an element and if left subtree data
is less than the element we want to search then skip it. Same is the
case with right subtree. In other words the binary seach tree
considers either the left or right subtree to search an element but
not both.
ALGORITHM:
a. Insertion:
1. If root == NULL create new node and return the same.
2. If root->data>=d
i. root->left=Insertion(root->left,d)
3. else root->right=Insertion(root->right,d)
b. deletion:
1. If root==NULL return NULL
2. if d<root->data
i. call deletinbst(root->left,d)
ii. return root
3. else if (d==root->d)
-return NULL
-node* temp=root->right
- delete root
- return temp
-node* temp=root->right
- delete root
- return temp
root->data=rep->data;
root->right=deleteinbst(root->right,rep->data);
return root;
4. else
root->right=deleteinbst(root->right,d);
return root;
c. searching:
1.if(root is NULL)
return false;
2. if(root->data==key)
return true;
3.else if(key<=root->data)
return searchh(root->left,key);
d. traversal:
(inorder)
CODE:
#include<iostream>
/*5 3 7 1 6 8 -1*/
class node
public:
int data;
node* left;
node* right;
node(int d)
data=d;
left=right=NULL;
};
if(!root)
return;
printin(root->left);
cout<<root->data<<",";
printin(root->right);
if(!root)
if(root->data>=d)
root->left=insertbst(root->left,d);
else
root->right=insertbst(root->right,d);
node* build()
int d;
cin>>d;
node* root=NULL;
while(d!=-1)
root=insertbst(root,d);
cin>>d;
return root;
if(!root)
return false;
if(root->data==key)
return true;
if(key<=root->data)
return searchh(root->left,key);
return searchh(root->right,key);
if(!root)
return NULL;
if(d<root->data)
root->left=deleteinbst(root->left,d);
return root;
else if(root->data==d)
if(root->left==NULL&&root->right==NULL)
{
delete root;
return NULL;
if(root->left==NULL&&root->right!=NULL)
node* temp=root->right;
delete root;
return temp;
if(root->left!=NULL&&root->right==NULL)
node* temp=root->left;
delete root;
return temp;
node* rep=root->right;
while(rep->left!=NULL)
rep=rep->left;
}
root->data=rep->data;
root->right=deleteinbst(root->right,rep->data);
return root;
else
root->right=deleteinbst(root->right,d);
return root;
int main()
node* root=build();
printin(root);
int d;
cin>>d;
if(searchh(root,d))
{
cout<<"\npresent\n";
else{
cout<<"\nabsent\n";
cin>>d;
root=deleteinbst(root,d);
printin(root);
return 0;
OUTPUT:
DISCUSSION:
As we can clearly see from the output figure the inorder traversal
of a binary search tree is always sorted.
LEARNING:
Breadth-First Search (BFS) is an algorithm used to traverse through all of the nodes within
a graph, tree, etc. It uses a Queue, which is a list of the nodes the algorithm is
going to visit, and the algorithm ends when the Queue is empty indicating that
their are no more nodes to be visited). In order for the algorithm to work, you
must give it a starting node, which is where the algorithm will start traversing from. The
algorithm enqueues the starting node to the Queue. As long as the Queue isn't
empty, it means that there's still nodes to navigate through. So the algorithm
dequeues a node from the Queue to analyze. For the node, the algorithm finds
its children, and if the node hasn't been visited, it adds them to the list of nodes
to be visited (the Queue), and marks them as visited. The important part is to only
add the node to the queue if it hasn't been visited. Otherwise, you will be traversing
through the same node again, and that can cause problems.
ALGORITH
M:
BFS-
A(G,s
)
for all v in
V[G] do
visited[v]
:= false
en
d
fo
r
Q=
EmptyQu
eue
Enqueue(Q,s)
while not
Empty(Q)
do
u :=
Dequeue(
Q)
if not
visited[u]
then
visited[u] :=
true
for all w in
Adj[u][w] do
if not
visited[w]
then
Enqueu
e(Q,w)
e
n
d
if
end for
end if
end while
FLOWCHART:
yes
At the end of the adjacency matrix
no
Has the node already been visited?
Put the node on the queue and mark it. Its now been visited.
Yes Move to the next node on the adjacency matrix
V. Code:
#include<stdio.h>
#define initial 1
#define waiting 2
#define visited 3
int n;
int adj[MAX][MAX];
int
state[MAX]
;
void
create_gra
ph();
void
BF_Travers
al();
void
BFS(int
v);
int
delete_queue
();
int
isEmpty_qu
eue();
int
main
()
create_gr
aph();
BF_Tra
versal()
; I
v
e
retu
rn
0;
void
BF_Traver
sal()
i
n
t
v
;
for(v=0; v<n;
vt)
state[v]
=
initial;
printf("Enter Start Vertex for
BFS: \n");
scanf("%d",
&v);
BFS
(v);}
void
BFS(int v)
i
n
t
i
;
insert_que
ue(v);
state[v] =
waiting;
while(!isEmpty_queue()
v=delete_queue();
printf("%d ",v);
state[v] = visited;
for(i=0; i<n; i++)
insert_queue(i);
state[i] = waiting;
printf("\n");
if(rear ==MAX-1)
printf("Queue Overflow\n");
else
if(front==-1)
front = 0;
rear = rear+1;
queue[rear] = vertex ;
int
isEmpty_que
ue()
if(fro
nt =
-1 || front >
rear)
retur
n 1;
e
l
s
e
retu
rn
0;
int
delete_qu
eue
int
delete_it
em;
printf("Queue
Underflow\n");
exi
t(1
);
delete_item =
queue[front];
front =
front+1;
return
delete_item;
void
create_grap
h()
int
count,max_edge,origin,d
estin;
printf("Enter number of
vertices :");
scanf("%d
",&n);
max_edge = n*(n-1);
for(count=1; count<=max_edge; count++)
scanf("%d %d",&origin,&destin);
else
{ adj[origin][destin] = 1;
V. Output:
Enter edge 4-1 -1 to quit ): 1. Enter edge SC 1-1 to quit ): 3 Enter edge 60 -1 -1 to quit ): 4
Enter edge 7 -1 -1 to quit ):6 Enter edoc B-1 -1 to quit ): 6 Enter edge 1.1 to quit ): 2
Enter edge 106.1 to quit ) : 4
81 342 6 5 7 8
tusharsenitusharsant-Lenevo-G50-70:- / Desktops
VI. Learning:
_BFS doesn't work too well if your graph / tree is very wide (nodes have many
children). It is more efficient if your graph/ tree is narrow.
The time complexity is O(IV + E), V being the vertices. This is because if
you want to
traverse every single node in the graph, you need to go through all of the nodes and
edges as well (you have to follow the connections nodes have to other nodes).
PROGRA
M-14
2. Initialize visited[ ] to
false (0) 3. for
(i=0;i<n;i++)
visited[i]
= 0;
FLOWCH
ART:
Visit and mark the first node of the graph
V. Code:
#include<stdio.h>
#include<stdlib.h>
void main()
int i; read_graph();
for(i=0;i<n;i++) visited[i]=0;
DFS(0);
void
DFS(int
i)
{
node *p;
printf("\n%d",
i); p=G[i];
visited[i]=1
;
while(p!=NU
LL)
i=p-
>vertex
;
if(!visite
d[i])
DFS(i
); p=p-
>next;
void
read_grap
h()
scanf("%d",
&n);
for(i=0;i<
n;i++)
G[i]=N
ULL;
printf("Enter number of
edges:");
scanf("%d",&no_o
f_edges);
for(i=0;i<no_of_
edges;i++)
printf("Enter an
edge(u,v):");
%d%d",&vi,&vj); insert(vi,vj);
void insert(int
vi,int vj)
node
*p,*q;
q=(node*)malloc(sizeof(node));
q->vertex=vj;
q->next=NULL; if(G[vi]==NULL)
G[vi]=q; else
p=G[vi];
while(p->next!=NULL) p=p->next; p->next=q;
VI. Output:
VII. Learning:
• The Time complexity of DFS will be O(V + E), where V is the
number
of vertices, and E is the number of Edges. This again depends
on the data strucure that we user to represent the graph. If it is an
adjacency matrix, it will be O(V^2). If we use an adjacency list, it will
be O(V+E). If our graph is implemented using adjacency
lists, wherein each node maintains a list of all its adjacent
edges, then, for each node, you could discover all its
neighbours by traversing its adjacency list just once in linear
time. For a directed graph, the sum of the sizes of the adjacency
lists of all the nodes is E (total number of edges). So, the
complexity of DFS is O(V) +O(E) = O(V+E).