Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Ds Whole

Download as pdf or txt
Download as pdf or txt
You are on page 1of 40

PROGRAM 4

AIM: WAP to perform push and pop operations on a stack


implemented using linked list.

THEORY: The other way of implementing the stack is by using linked


list. Push operation is implemented by inserting element at the
beginning of linked list. Pop operation is implemented by deleting
the node from the beginning of the linked list.

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>

using namespace std;

struct node
{

int data;

struct node* next;

};

struct node* Createstack()

return NULL;

int Isempty(struct node* top)

return top==NULL;

void push(struct node**top,int d)

struct node* temp=(struct node*)malloc(sizeof(struct node));

temp->data=d;

temp->next=*top;

*top=temp;

int pop(struct node**top)


{

int d;

struct node* temp;

if(Isempty(top))

return -1;

temp=*top;

*top=(*top)->next;

d=temp->data;

free(temp);

return d;

int main()

struct node* top=Createstack();

cout<<"Enter the data you want to put in stack\nPress -1 to stop


providing the input\n";

int d;

cin>>d;

while(d!=-1)

push(&top,d);
cin>>d;

cout<<"After performing pop operation on the stack"<<endl;

while(!Isempty(top))

cout<<pop(&top)<<" ";

return 0;

OUTPUT:

DISCUSSION:

Every operation takes O(1) constant time.

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 .

THEORY: Array implementation of stack using stack ADT uses an


array. In the array, we add elements from left to right and use a
variable to keep track of the index of top element. The array storing
elements may become full. A push operation will then throw a full
stack exception. Similarly if we try deleting an element from an
empty stack it will throw stack empty exception.

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>

using namespace std;

struct arraystack
{

int top;

int capacity;

int *arr;

};

struct arraystack* Createstack()

struct arraystack* s=(struct arraystack*)malloc(sizeof(struct


arraystack));

if(!s)

return NULL;

s->capacity=10;

s->top=-1;

s->arr=(int* )malloc((s->capacity*sizeof(int)));

return s;

};

int Isfull(struct arraystack*s)

return (s->top==s->capacity-1);

int Isempty(struct arraystack* s)

{
return (s->top==-1);

void push(struct arraystack*s,int d)

if(Isfull(s))

cout<<"Stack overflow\n";

else

s->arr[++s->top]=d;

int pop(struct arraystack*s)

if(Isempty(s))

cout<<"stack is empty\n";

else

return (s->arr[s->top--]);

int main()
{

struct arraystack* s=Createstack();

int d;

cout<<"Enter the elements to push.\nIn order to stop giving the


input press -1\n";

cin>>d;

int i=1;

while(d!=-1&&i<=10)

push(s,d);

cin>>d;

cout<<endl<<"The value of top index is:"<<s->top<<endl;

cout<<"After performing pop on the stack\n";

i=1;

while(i<=11&&!Isempty(s))

cout<<pop(s)<<" ";

i++;

return 0;

}
OUTPUT:

DISCUSSION:

In this program we created a stack with array implementation. We


performed push and pop on the same.

LEARNING OUTCOME:

Here in this program I learned to perform push, pop, Isempty, Isfull


operations on stack. It improved my understanding of stack data
structure.
PROGRAM 7

AIM: Write a Program to implement a queue using array and


perform basic queue operations.

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

 Step 1 − Check if the queue is full.


 Step 2 − If the queue is full, produce overflow error and exit.
 Step 3 − If the queue is not full, increment rear pointer to point
the next empty space.
 Step 4 − Add data element to the queue location, where the rear
is pointing.
 Step 5 − return success.
Dequeue Operation
 Step 1 − Check if the queue is empty.
 Step 2 − If the queue is empty, produce underflow error and
exit.
 Step 3 − 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.
 Step 5 − Return success.

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)

i. if (it has no left or right children)


-delete root

-return NULL

ii. if (it has left child but no right child)

-node* temp=root->right

- delete root

- return temp

iii. if(it has no right child but right chid)

-node* temp=root->right

- delete root

- return temp

iv. if(it has both left and right child)

-traverse using a temporary node to the leftmost


child and then

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

4. else return searchh(root->right,key);

d. traversal:

(inorder)

1. traverse the right subtree in order

2. visit the root

3. traverse the right subtree in order.

CODE:

#include<iostream>

using namespace std;

/*5 3 7 1 6 8 -1*/

class node

public:

int data;

node* left;

node* right;
node(int d)

data=d;

left=right=NULL;

};

void printin(node* root)

if(!root)

return;

printin(root->left);

cout<<root->data<<",";

printin(root->right);

node* insertbst(node* root,int d)

if(!root)

return new node(d);

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;

bool searchh(node* root,int key)

if(!root)
return false;

if(root->data==key)

return true;

if(key<=root->data)

return searchh(root->left,key);

return searchh(root->right,key);

node* deleteinbst(node* root,int d)

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

cout<<"Enter the elements in the binary search tree.\nPress -1 if


current node is NULL."<<endl;

node* root=build();

cout<<"\nThe inorder traversal of BST gives following order:\n";

printin(root);

cout<<"\nEnter the element you want to search\n";

int d;

cin>>d;

if(searchh(root,d))

{
cout<<"\npresent\n";

else{

cout<<"\nabsent\n";

cout<<"Enter the element you want to delete\n";

cin>>d;

root=deleteinbst(root,d);

cout<<"The inorder traversal of tree after deletion of "<<d<<" is:


\n"<<endl;

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:

The time complexity of inorder traversal is O(n).

Its space complexity is also O(n).

The basic operations on binary search tree take time proportional to


height of the tree.

Hence there exist variations in time complexities of best case


average case and worst case.
PROGRAM
– 13
A
I
M
:
Write a program to traverse in a Graph using
Breadth First Search(BFS).
THE
ORY
:

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:

Visit and mark the first node of graph

Put the first node into the queue


Done
yes
Is the queue empty?
I no Remove a node from the queue

Point to the first entry n that node's adjacency list

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>

#include<stdlib.h> #define MAX 100

#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 queue[MAX], front


= -1,rear =-1;
void insert_queueint
vertex);

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

if(adj[v][i] == 1 && state[i] == initial)

insert_queue(i);
state[i] = waiting;

printf("\n");

void insert_queueint vertex)

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;

if(front=-1 || front >


rear)

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

printf("Enter edge %d( -1 -1 to quit ) : ",count);

scanf("%d %d",&origin,&destin);

if((origin ==-1) && (destin=-1))


break;

else

{ adj[origin][destin] = 1;

V. Output:

tusharsontatusharsont-Lenovo-G50-70:-/Desktops ...out Enter nunber of vertices : 9 Enter edge


10 -1 -1 to quit ):
Enter edge 21 -1 -1 to quit ): 0 Enter edoe 31 -1 to quite

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

Enter edge 11 -1 -1 to quit ): 7 Enter edge 12 -1 -1 to quit ) : 7


Enter edge 13 -1 -1 to quit ): -1
Fnter Start Vertex Tor BFS:

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

AIM: Write a program to implement Depth


First Search (DFS) in a Graph THEORY:
Traversal of a graph means visiting each node and
visiting exactly once. There are two types of traversal in
graphs i.e. Depth First Search (DFS) and Breadth First
Search (BFS). It is like tree . Traversal can start from any
vertex, say Vi. V; is visited and then all vertices adjacent to V;
are traversed recursively using DFS. Since, a graph can have
cycles. We must avoid revisiting a node. To do this, when we visit a
vertex V, we mark it visited. A node that has already been marked as
visited should not be selected for traversal. Marking of visited
vertices can be done with the help of a global array visited [].
Array visited [] is initialized to false (0).
ALGORIT
HM:
1. nt number of
nodes

2. Initialize visited[ ] to
false (0) 3. for
(i=0;i<n;i++)
visited[i]
= 0;

4. void DFS(vertex i) [DFS


starting from i]
visited[i]=1; for each w adjacent to i
if(!visited[w])
DF
S(w
);

FLOWCH
ART:
Visit and mark the first node of the graph

Put to the first entry in the rode's adjacency list

At the end of the adjacency list?


Done

Has the node already been visited?


Perform this algorithm with the node as the first one
Yes Move to the next node on the adjacency list

V. Code:
#include<stdio.h>

#include<stdlib.h>

typedef struct node

struct node *next;


int vertex; }node; node *G[20]; int visited[20]; int n; void read
graph(); void insert(int,int); void DFS(int);

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

int i,vi, vj,no_of_edges; printf("Enter


number of vertices:");

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:

C:\Users\Student\Documents\program.exe Enter number of vertices: 8 Enter number of edges:


10 Enter an edge(u, v): 0 1 Enter an edge(u, v): 0 2 Enter an edge(u, v): 0 3 Enter an edge (u,
v):04 Enter an edge(u, v):1 5 Enter an edge (u, v):2 5 Enter an edge(u, v):3 6 Enter an edge(u,
v):4 6 Enter an edge(u, v):57 Enter an edgeu,v):6 7
ONME
Or NNM

Process returned 0 (0x0) Press any key to continue.


execution time: 28.955 s

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

You might also like