You are on page 1of 98

1

Week-1

AIM: To write C++ programs to implement the following using an array.


a) Stack ADT b) Queue ADT

Description:

One of the most common forms of data organization in computer programs is the
ordered or linear list, which is often written as a = (a1, a2, .., an). A stack is an
ordered list in which all insertions and deletions are made at one end, called the top. A
queue is an ordered list in which all insertions take place at one end, the rear, whereas
all deletions take place at the other end, the front.

The operations of a stack imply that if the elements A, B, C, D and E are inserted into a
stack, in that order, then the first element to be removed must be E. Equivalently we
say that the last element to be inserted into the stack is the first to be removed. For
this reason stacks are sometimes referred to as Last In First Out (LIFO) lists. The
operations of a queue require that the first element that is inserted into the queue is
the first one to be removed. Thus queues are known as First In First Out (FIFO) lists.

Above figure shows the examples of a stack and queue each containing the same five
elements inserted in the same order.

The simplest way to represent a stack is by using a one-dimensional array, say stack[0
: n-1], where n is the maximum number of allowable entries. The first or bottom
element in the stack is stored at stack[0], the second at stack[1], and i th at stack[i-1].
Associated with the array is a variable, typically called top, which points to the top
element, to test whether the stack is empty, we ask if (top<0). If not, the topmost
element is at stack[top]. Checking whether the stack is full can be done by asking if
(top n-1). Two more substantial operations are inserting and deleting elements. The
corresponding algorithms are Add and Delete.
2

Implementation:

#include<iostream.h>
#include<conio.h>
class stack
{
int m;
int top;
int *s;
public :
stack(int);

void push(int);
int pop();
int isempty();
int isfull();
void display();
~stack();
};
stack::stack(int maxsize)
{
m=maxsize;
top=-1;
s=new int(m);
}
void stack::push(int x)
{
if(isfull())
cout<<"Stack is full"<<endl;
else
{
top++;
s[top]=x;
}
}
int stack ::pop()
{
if(isempty())
return -1;
else
{
int x=s[top];
top--;
return x;
}
}
int stack::isempty()
{
if(top==-1)
return 1;
else
return 0;
}
int stack :: isfull()
{
if(top==m-1)
return 1;
else
return 0;
}
3

void stack::display()
{
if(isempty())
cout<<"Empty list"<<endl;
else
{
for(int i=top;i>=0;i--)
cout<<s[i]<<" ";
cout<<endl;
}
}
stack::~stack()
{
delete [] s;
}
void menu()
{
cout<<"1.Insert"<<endl;
cout<<"2.Delete"<<endl;
cout<<"3.Display"<<endl;
cout<<"4.Exit"<<endl;
}
void main()
{
clrscr();
int ch;
int x,r;
stack st(10);
menu();
cout<< Enter your choice::;
cin>>ch;
while(ch<4)
{
switch(ch)
{
case 1:
cout<<"Enter element"<<endl;
cin>>x;
st.push(x);
cout<<endl<<data is pudhed..;
break;
case 2:
r=st.pop();
if(r==-1)
cout<<"Element cannot be deleted as stack is
empty"<<endl;
else
cout<<"Deleted element is "<<r<<endl;
break;
case 3:
st.display();
break;
}
menu();
cout<< Enter your choice::;
cin>>ch;
}
getch();
}
4

Output:

1. Insert
2. Delete
3. Display
4. Exit
Enter your choice::1
Enter element 6
Data is pushed..

1. Insert
2. Delete
3. Display
4. Exit
Enter your choice::1
Enter element 7
Data is pushed..
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice::3
6 7
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice::3
Enter element 7
Data is pushed..
5

Queue ADT

AbstractDataType queue
{
instances
ordered list of elements; one end is called the front; the other is the back;

operations

empty( ) : return true if the queue is empty, return false otherwise;


size( ) : return the number of elements in the queue
front ( ) : return the front element of the queue
back( ) : return the back element of the queue
pop( ) : remove the top element from the queue
push(x) : add element x at the top of the queue
}
6

Implementation:
#include<iostream.h>
#include<conio.h>
template <class T>
class queue
{
int m;
int f,r;
T *q;
public:
queue();
void insert(T);
T del();
int isfull();
int isempty();
void display();
T first();
T last();
};

template <class T>


queue<T>::queue()
{
f=0;
r=-1;
q=new T(10);
m=10;
}

template <class T>


int queue<T>::isempty()
{
if(r==-1)
return 1;
else
return 0;
}

template <class T>


int queue<T>::isfull()
{
if(r==m-1)
return 1;
else
return 0;
}

template <class T>


void queue<T>::insert(T x)
{
if(isfull())
cout<<"queue full"<<endl;
else
{
r++;
q[r]=x;
}
}

template <class T>


7

T queue<T>::del()
{
T x;
if(isempty())
return -1;
else
if(r==f)
{
x=q[f];
r=-1;
f=0;
return x;
}
else
{
x=q[f];
f++;
return x;
}
}

template <class T>


T queue<T>::first()
{
if(isempty())
return -1;
else
return q[f];
}

template <class T>


T queue<T>::last()
{
if(isempty())
return -1;
else
return q[r];
}

template <class T>


void queue<T>::display()
{
if(r==-1)
cout<<"Empty queue"<<endl;
else
{
Cout<< Elements are ::<<endl;
for(int i=f;i<=r;i++)
cout<<q[i]<<" ";
cout<<endl;
}
}

void menu1()
{
cout<<"1.Interger queue"<<endl;
cout<<"2.Float queue"<<endl;
cout<<"3.Character queue"<<endl;
}
8

void menu2()
{
cout<<"1.Insert"<<endl;
cout<<"2.Delete"<<endl;
cout<<"3.Display"<<endl;
cout<<"4.display first elemant"<<endl;
cout<<"5.display last element"<<endl;
cout<<"6.Exit"<<endl;
}

template <class T>


void queueop(queue<T> q)
{
int ch;
T x,r;
menu2();
cout<< " Enter your choice :: " ;
cin>>ch;
while(ch<6)
{
switch(ch)
{
case 1:
cout<<"Enter element"<<endl;
cin>>x;
q.insert(x);
cout<<Element inserted;
break;
case 2:
r=q.del();
if(r==-1)
cout<<"Element cannot be deleted as stack is
empty"<<endl;
else
cout<<"Deleted element is "<<r<<endl;
break;
case 3:
q.display();
break;
case 4:
r=q.first();
if(r==-1)
cout<<"Empty queue"<<endl;
else
cout<<"first element is"<<r<<endl;
break;
case 5:
r=q.last();
if(r==-1)
cout<<"Empty queue"<<endl;
else
cout<<"last element is"<<r<<endl;
break;
}
menu2();
cin>>ch;
}
}

void main()
9

{
clrscr();
int ch;
menu1();
cout<<Enter your choice::;
cin>>ch;
if(ch<4)
{
switch(ch)
{
case 1:
queue<int> q;
queueop(q);
break;

case 2:
queue<float> q;
queueop(q);
break;
case 3:
queue<char> q;
queueop(q);
break;

default :
break;
}
}
getch();
}

Output:

1. Integer queue
2. Float queue
3. Character queue
Enter your choice::1
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 1
Enter element 5
Element inserted

1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 1
Enter element 6
Element inserted
1. Insert
2. Delete
3. Display
10

4. Display first element


5. Display last element
Enter your choice:: 1
Enter element 7
Element inserted
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 3
Enter elements
5 6 7
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 2
Deleted element 5
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 4
First element 6
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 5
Last element 7
4.
11

Week-2

AIM: To write C++ programs to implement the following using a singly linked list.
a)Stack ADT b) Queue ADT

Implementation:

a) Stack ADT

#include<iostream.h>
#include<conio.h>
template <class T>
class stack
{
struct node
{
T data;
node *link;
}* top;
public:
stack();
void push(T);
T pop();
void display();
~stack();
};

template <class T>


stack<T>::stack()
{
top=0;
}

template <class T>


void stack<T>:: push(T x)
{
node *p=new node;
pdata=x;
plink=top;
top=p;
}

template <class T>


T stack<T>::pop()
{
node *temp=top;
top=toplink;
T x=tempdata;
delete temp;
return x;
}

template <class T>


void stack<T>::display()
{
if(top==0)
cout<<"Empty stack"<<endl;
else
{
12

node* temp=top;
while(temp!=0)
{
cout<<tempdata<<" ";
temp=templink;
}
cout<<endl;
}
}

template <class T>


stack<T>::~stack()
{
node *temp;
while(top!=0)
{
temp=top;
top=toplink;
delete temp;
}
}

void menu1()
{
cout<<"1.Interger stack"<<endl;
cout<<"2.Float stack"<<endl;
cout<<"3.Character stack"<<endl;
}

void menu2()
{
cout<<"1.Insert"<<endl;
cout<<"2.Delete"<<endl;
cout<<"3.Display"<<endl;
cout<<"4.Exit"<<endl;
}

template <class T>


void stackop(stack<T> st)
{
int ch;
T x,r;
menu2();
cout<< Enter your choice :: ;
cin>>ch;
while(ch<4)
{
switch(ch)
{
case 1:
cout<<"Enter element"<<endl;
cin>>x;
st.push(x);
cout<<Element inserted;

break;
case 2:
r=st.pop();
if(r==-1)
13

cout<<"Element cannot be deleted as stack is


empty"<<endl;
else
cout<<"Deleted element is "<<r<<endl;
break;
case 3:
st.display();
break;
}
menu2();
cout<< Enter your choice :: ;
cin>>ch;
}
}

void main()
{
clrscr();
int ch;
menu1();
cin>>ch;
if(ch<4)
{
switch(ch)
{
case 1:
{
stack<int> s;
stackop(s);
break;
}
case 2:
{
stack<float> s;
stackop(s);
break;
}
case 3:
{
stack<char> s;
stackop(s);
break;
}
default :
break;
}
}
getch();
}

1. Integer stack
2. Float stack
3. Character stack
Enter your choice::1
1. Insert
2. Delete
3. Display
Enter your choice:: 1
Enter element 5
14

Element inserted

1. Insert
2. Delete
3. Display

Enter your choice:: 1


Enter element 6
Element inserted
1. Insert
2. Delete
3. Display
Enter your choice:: 1
Enter element 7
Element inserted
1. Insert
2. Delete
3. Display
Enter your choice:: 3
Enter elements
5 6 7
1. Insert
2. Delete
3. Display
Enter your choice:: 2
Deleted element 7
15

b) Queue ADT

#include <iostream.h>
#include <conio.h>
template <class T>
struct node
{
T data;
node *link;
};

template <class T>


class queue
{
node<T> *f,*r;
public:
queue();
void insert(T);
T del();
void display();
T first();
T last();
};

template <class T>


queue<T>::queue()
{
f=0;
r=0;
}

template <class T>


void queue<T> :: insert(T x)
{
node<T> *p=new node<T>;
pdata=x;
plink=0;
if(f==0)
{
f=p;
r=p;
}
else
{
rlink=p;
r=p;
}
}

template <class T>


T queue<T>::del()
{
if(f==0)
return -1;
else
{
node<T> *temp=f;
T x=tempdata;
f=flink;
return x;
16

}
}

template <class T>


void queue<T> ::display()
{
if(f==0)
cout<<"Empty queue"<<endl;
else
{
node<T> *temp=f;
while(temp!=0)
{
cout<<tempdata<<" ";
temp=templink;
}
cout<<endl;
}
}

template <class T>


T queue<T>::first()
{
if(f==0)
return -1;
else
return fdata;
}

template <class T>


T queue<T>::last()
{
if(f==0)
return -1;
else
return rdata;
}

void menu1()
{
cout<<"1.Interger queue"<<endl;
cout<<"2.Float queue"<<endl;
cout<<"3.Character queue"<<endl;
}

void menu2()
{
cout<<"1.Insert"<<endl;
cout<<"2.Delete"<<endl;
cout<<"3.Display"<<endl;
cout<<"4.display first elemant"<<endl;
cout<<"5.display last element"<<endl;
cout<<"6.Exit"<<endl;
}

template <class T>


void queueop(queue<T> q)
{
int ch;
T x,r;
17

menu2();
cin>>ch;
while(ch<6)
{
switch(ch)
{
case 1:
cout<<"Enter element"<<endl;
cin>>x;
q.insert(x);
break;
case 2:
r=q.del();
if(r==-1)
cout<<"Element cannot be deleted as stack is
empty"<<endl;
else
cout<<"Deleted element is "<<r<<endl;
break;
case 3:
q.display();
break;
case 4:
r=q.first();
if(r==-1)
cout<<"Empty queue"<<endl;
else
cout<<"first element is"<<r<<endl;
break;
case 5:
r=q.last();
if(r==-1)
cout<<"Empty queue"<<endl;
else
cout<<"last element is"<<r<<endl;
break;
}
menu2();
cin>>ch;
}
}

void main()
{
clrscr();
int ch;
menu1();
cin>>ch;
if(ch<4)
{
switch(ch)
{
case 1:

queue<int> q;
queueop(q);
break;

case 2:
18

queue<float> q;
queueop(q);
break;

case 3:

queue<char> q;
queueop(q);
break;

default :
break;
}
}
getch();
}

Output:

1. Integer queue
2. Float queue
3. Character queue
Enter your choice::1
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 1
Enter element 5
Element inserted

1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 1
Enter element 6
Element inserted
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 1
Enter element 7
Element inserted
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 3
19

Enter elements
5 6 7
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 2
Deleted element 5
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 4
First element 6
1. Insert
2. Delete
3. Display
4. Display first element
5. Display last element
Enter your choice:: 5

Last element 7
20

Week-3

AIM: To Write C++ programs to implement the deque (double ended queue) ADT
using a
doubly linked list and an Array.

Description:

Doubly Linked Lists

One shortcoming of singly linked list is we can only move forwards through the list. A
doubly linked list is a linked list, which also has pointers from each element to the
preceding element. Doubly linked list make manipulation of lists easier.

A double-ended queue is a linear list for which insertions and deletions can occur at
either end i.e., deque supports insertion and deletion from the front and back.

The Deque Abstract Data Type


insertFirst(e): Insert e at the beginning of deque.
insertLast(e): Insert e at end of deque
removeFirst(): Removes and returns first element
removeLast(): Removes and returns last element

Additionally supported methods include:

To Implement Deque with Doubly Linked Lists we use a doubly linked list with
special header and trailer nodes

When implementing a doubly linked list, we add two special nodes to the ends of the
lists: the header and trailer nodes.
The header node goes before the first list element. It has a valid next link but a
null prev link.
The trailer node goes after the last element. It has a valid prev reference but a
null next reference.

NOTE: the header and trailer nodes are sentinel or dummy nodes because they do
not store elements. Heres a diagram of our doubly linked list:

DEQUE Implementation

#include<iostream.h>
21

#include<conio.h>
struct node
{
node *llink;
int data;
node *rlink;
};

class dlink
{
node *l;
node *r;
public:
dlink();
void append(int);
void display();
int isempty();
int length();
int insert(int,int);
int del(int i,int& x);
int find(int i,int& x);
int search(int& i,int x);
};

dlink::dlink()
{
l=0;
r=0;
}

void dlink::append(int x)
{
node *temp,*p;
p=new node;
p->data=x;
if(l==0)
{
p->llink=0;
p->rlink=0;
l=p;
r=p;
}
else
{
r->rlink=p;
p->llink=r;
p->rlink=0;
r=p;
}
}

void dlink::display()
{
node *temp;
if(l==0)
cout<<"emptylist"<<endl;
else
{
temp=l;
22

while(temp!=0)
{
cout<< temp->data<<" ";
temp=temp->rlink;
}
}
}

int dlink::isempty()
{
if((l==0)&&(r==0))
return 1;
else
return 0;
}

int dlink::length()
{
if(isempty())
return 0;
else
{
int len=1;
node *temp=l;
while(temp->rlink!=0)
{
len++;
temp=temp->rlink;
}
return len;
}
}

int dlink::insert(int i,int x)


{
if(i<0||i>length())
return 0;
else
{
node *p;
p=new node;
p->data=x;
if(l==0)
{
p->llink=0 ;
p->rlink=0;
l=p;
r=p;
}
else
if(i==0)
{
p->rlink=l;
p->llink=0;
l->llink=p;
l=p;
}
else
if(i==length())
{
23

p->llink=r;
p->rlink=0;
r->rlink=p;
r=p;
}
else
{
node *temp=l;
for(int j=1;j<i;j++)
temp=temp->rlink;
p->llink=temp;
p->rlink=temp->rlink;
temp->rlink=p;
(temp->rlink)->llink=p;
}
return 1;
}
}

int dlink::del(int i,int& x)


{
if(i<1||i>length())
return 0;
else
{
node *temp;
if(length()==1)
{
temp=l;
l=0;
r=0;
x=temp->data;
delete temp;
}
else
if(i==1)
{
temp=l;
l=l->rlink;
x=temp->data;
delete temp;
}
else
if(i==length())
{
temp=r;
r=r->llink;
r->rlink=0;
x=temp->data;
delete temp;
}
else
{
node *prev,*next;
temp=l;
for(int j=1;j<i;j++)
temp=temp->rlink;
prev=temp->llink;
next=temp->rlink;
24

prev->rlink=next;
next->llink=prev;
x=temp->data;
delete temp;
}
return 1;
}
}

int dlink::find(int i,int& x)


{
if(i<1||i>length())
return 0;
else
{
node *temp;
temp=l;
for(int j=1;j<i;j++)
temp=temp->rlink;
x=temp->data;
return 1;
}
}

int dlink::search(int& i,int x)


{
if(isempty())
return 0;
else
{
node *temp=l;
int len=1;
while(temp!=0)
{
if(temp->data==x)
{
i=len;
return 1;
}
else
{
len++;
temp=temp->rlink;
}
}
return 0;
}
}

void menu()
{
cout<<"Enter 1 to append"<<endl;
cout<<"Enter 2 to display"<<endl;
cout<<"Enter 3 to insert"<<endl;
cout<<"Enter 4 to delete"<<endl;
cout<<"Enter 5 to find the ith element"<<endl;
cout<<"Enter 6 to search for an element"<<endl;
cout<<"Enter 7 to exit"<<endl;
}
25

void main()
{
clrscr();
dlink dl;
int choice,i,x,r;
menu();
cout<<Enter your choice::;
cin>>choice;
while(choice<7)
{
switch(choice)
{
case 1:
{
cout<<"Enter the element to be appended"<<endl;
cin>>x;
dl.append(x);
cout<< element appended..;
break;
}
case 2:
{
dl.display();
break;
}
case 3:
{
cout<<"Enter the position and element"<<endl;
cin>>i>>x;
r=dl.insert(i,x);
if(r==0)
cout<<"Invalid position"<<endl;
else
cout<<"Element inserted"<<endl;
break;
}

case 4:
{
cout<<"Enter the position"<<endl;
cin>>i;
r=dl.del(i,x);
if(r==0)
cout<<"Invalid position"<<endl;
else
cout<<"deleted element is "<<x<<endl;
break;
}
case 5:
{
cout<<"Enter the position"<<endl;
cin>>i;
r=dl.find(i,x);
if(r==0)
cout<<"Invalid position"<<endl;
else
cout<<i<<"th element is "<<x<<endl;
break;
}
case 6:
26

{
cout<<"Enter the element to search"<<endl;
cin>>x;
r=dl.search(i,x);
if(r==0)
cout<<"Element not found"<<endl;
else
cout<<"Element found in "<<i<<" position"<<endl;
break;
}
}
menu();
cout<<Enter your choice::;
cin>>choice;
}
getch();
}
Output :

Enter 1 to append
Enter 2 to display
Enter 3 to insert
Enter 4 to delete
Enter 5 to find ith element
Enter 6 to search for an element
Enter 7 to exit.
Enter your choice:1
Enter the element to be appended: 5
Element appended.

Enter 1 to append
Enter 2 to display
Enter 3 to insert
Enter 4 to delete
Enter 5 to find ith element
Enter 6 to search for an element
Enter 7 to exit.
Enter your choice:1
Enter the element to be appended: 7
Element appended.
27

Week -4

AIM : To write a C++ program to perform the following operations:


a) Insert an element into a binary search tree.
b) Delete an element from a binary search tree.
c) Search for a key element in a binary search tree.

Description:
Binary Search Tree
A Binary search tree is a binary tree. It may be empty. If it not empty, then it satisfies
the following properties.
1. Every element has a key and no two elements have the same key.
2. The keys in the left subtree are smaller than the key in the root.
3. The keys in the right subtree are larger than the key in the root.
4. The left and right subtrees are also binary search trees.

ADT of Binary Search Tree


AbstractDataType bsTree

instances

binary trees, each node has a pair whose first component is a key and whose
second component is the value associated with the key; all keys are distinct;
keys in the left subtree of any node are smaller than the key in the node; those
in the right subtree are larger.

operations

find(k) : return the pair with the key k. }


insert(p) : insert the pair p into the search tree
erase(k) : delete the pair with key k;
ascend( ): output all pairs in ascending order of key.
A binary search tree can support the operations search, insert and delete among
others.

Searching a binary search tree : since the definition of a binary search tree is
recursive, it is easier to write a recursive search procedure.

Insertion into a binary search tree

If the root is 0, then the search tree contains no elements and the search is
unsuccessful. Otherwise, we compare x with the key in the root. If x equals the key,
then the search terminates successfully. If x is less than the key in the root, then no
element in the right subtree can have key value x, and only the left subtree is to be
searched. If x is larger than the key in the root, only the right subtree needs to be
searched.

Implementation:

#include<iostream.h>
#include<conio.h>
#include<process.h>
28

enum bool{false,true};
template <class T>
class Node
{
friend BST<T>;
private:
T data;
Node<T> *lchild,*rchild;
};

template <class T>


class BST
{
public:
BST()
{
root=NULL;
}
~BST();
void destroy(Node<T> *p);
bool search(const T &k);
void insert(const T &e);
void del(const T &k);
void display();
void preorder(Node<T> *p);
private:
Node<T> *root;
};

template<class T>
BST<T>::~BST()
{
destroy(root);
}

template<class T>
void BST<T>::destroy(Node<T> *p)
{
if(p)
{
destroy(p->lchild);
delete p;
destroy(p->rchild);
}
}

template<class T>
bool BST<T>::search(const T &k)
{
Node<T> *p=root;
while(p)
{
if(k<p->data)
p=p->lchild;
else if(k>p->data)
p=p->rchild;
else return true;
}
return false;
}
29

template<class T>
void BST<T>::insert(const T &e)
{
Node<T> *p=new Node<T>;
Node<T> *temp1=root,*temp2;
p->data=e;
p->lchild=p->rchild=NULL;
if(root==NULL)
root=p;
else
{
while(temp1)
{
temp2=temp1;
if(e<temp1->data)
temp1=temp1->lchild;
else if(e>temp1->data)
temp1=temp1->rchild;
else{
cout<<"\n element is already there \n";
return;
}
}
if(e>temp2->data)
temp2->rchild=p;
else temp2->lchild=p;
}
Cout<< element inserted;
}

template<class T>
void BST<T>::del(const T &k)
{
Node<T> *p=root;
Node<T> *temp=root,*temp2,*s;
while(p)
{
if(k<p->data)
{
temp=p;
p=p->lchild;
}
else if(k>p->data)
{
temp=p;
p=p->rchild;
}
else
{
cout<<p->data<<"is deleted\n";
temp2=p;
if(p->lchild)
{
s=p->lchild;
while(s->rchild)
{
temp2=s;
s=s->rchild;
}
30

if(temp2!=p)
temp2->rchild=s->lchild;
else
temp2->lchild=s->lchild;
}
else if(p->rchild)
{
s=p->rchild;
while(s->lchild)
{
temp2=s;
s=s->lchild;
}
if(temp2!=p)
temp2->lchild=s->rchild;
else
temp2->rchild=s->rchild;
}
else
{
s=p;
if(p->data>temp->data)
temp->lchild=NULL;
else temp->lchild=NULL;
if(p==root)
root=NULL;
}
p->data=s->data;
p=NULL;
delete s;
return;
}
}
cout<<"\n element not found";
return;
}

template<class T>
void BST<T>::display()
{
if(root)
preorder(root);
else cout<<"there are no elements in bst\n";
}

template<class T>
void BST<T>::preorder(Node<T> *p)
{
if(p)
{
cout<<p->data<<"\t";
preorder(p->lchild);
preorder(p->rchild);
}
}

void main()
{
BST<int> q;
int i,ch,x;
31

char t;
clrscr();
do
{
cout<<"\n1.insert 2.search 3.delete 4.display 5.exit";
cout<<"\n enter the choice";
cin>>ch;
switch(ch)
{
case 1: cout<<"\n enter the element to be inserted:";
cin>>x;
q.insert(x);
break;
case 2: cout<<"\n enter the element to be search";
cin>>x;
if(q.search(x)) cout<<x<<"is found";
else
cout<<"element not found";
break;
case 3: cout<<"\nenter the element to be deleted";
cin>>x;
q.del(x);
break;
case 4: q.display();
break;
case 5: exit(0);
default: cout<<"\n entered wrong choice";
}
cout<<"\n do u want to continue{y/n} :";
cin>>t;
} while(t!='n' &&t!='N');
}
32

Output:

1. Insert
2. Search
3. Delete
4. Display
5. Exit
Enter your choice:1
Enter the element to be inserted:7
Element inserted.
1. Insert
2. Search
3. Delete
4. Display
5. Exit
Enter your choice:1
Enter the element to be inserted:8

Element inserted.

1. Insert
2. Search
3. Delete
4. Display
5. Exit
Enter your choice:1
Enter the element to be inserted:9

Element inserted.

1. Insert
2. Search
3. Delete
4. Display
5. Exit
Enter your choice:2
Enter the element to be search:8

8 is found.
33

Week -5

AIM: To write C++ programs that use recursive functions to traverse the given binary
tree in
a) Preorder b) inorder and c) postorder

Implementation:

#include <iostream>
#include <cstdlib>
using namespace std;

class BinarySearchTree
{
private:
struct tree_node
{
tree_node* left;
tree_node* right;
ints data;
};
tree_node* root;
public:
BinarySearchTree()
{
root = NULL;
}
bool isEmpty() const { return root==NULL; }
void print_inorder();
void inorder(tree_node*);
void print_preorder();
void preorder(tree_node*);
void print_postorder();
void postorder(tree_node*);
void insert(int);
void remove(int);
};

// Smaller elements go left


// larger elements go right
void BinarySearchTree::insert(int d)
{
tree_node* t = new tree_node;
tree_node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
// is this a new tree?
if(isEmpty())
root = t;
else
{
//Note: ALL insertions are as leaf nodes
tree_node* curr;
curr = root;
// Find the Node's parent
while(curr)
{
34

parent = curr;
if(t->data > curr->data)
curr = curr->right;
else
curr = curr->left;
}

if(t->data < parent->data)


parent->left = t;
else
parent->right = t;
}
}

void BinarySearchTree::remove(int d)
{
//Locate the element
bool found = false;
if(isEmpty())
{
cout<<" This Tree is empty! "<<endl;
return;
}
tree_node* curr;
tree_node* parent;
curr = root;
while(curr != NULL)
{
if(curr->data == d)
{
found = true;
break;
}
else
{
parent = curr;
if(d>curr->data)
curr = curr->right;
else
curr = curr->left;
}
}
if(!found)
{
cout<<" Data not found! "<<endl;
return;
}

// 3 cases :
// 1. We're removing a leaf node
// 2. We're removing a node with a single child
// 3. we're removing a node with 2 children

// Node with single child


if((curr->left == NULL && curr->right != NULL)||(curr->left != NULL&&curr-
>right== NULL))
35

{
if(curr->left == NULL && curr->right != NULL)
{
if(parent->left == curr)
{
parent->left = curr->right;
delete curr;
}
else
{
parent->right = curr->right;
delete curr;
}
}
else // left child present, no right child
{
if(parent->left == curr)
{
parent->left = curr->left;
delete curr;
}
else
{
parent->right = curr->left;
delete curr;
}
}
return;
}

//We're looking at a leaf node


if( curr->left == NULL && curr->right == NULL)
{
if(parent->left == curr)
parent->left = NULL;
else
parent->right = NULL;
delete curr;
return;
}

//Node with 2 children


// replace node with smallest value in right subtree
if (curr->left != NULL && curr->right != NULL)
{
tree_node* chkr;
chkr = curr->right;
if((chkr->left == NULL) && (chkr->right == NULL))
{
curr = chkr;
delete chkr;
curr->right = NULL;
}
else // right child has children
{
//if the node's right child has a left child
// Move all the way down left to locate smallest element

if((curr->right)->left != NULL)
36

{
tree_node* lcurr;
tree_node* lcurrp;
lcurrp = curr->right;
lcurr = (curr->right)->left;
while(lcurr->left != NULL)
{
lcurrp = lcurr;
lcurr = lcurr->left;
}
curr->data = lcurr->data;
delete lcurr;
lcurrp->left = NULL;
}
else
{
tree_node* tmp;
tmp = curr->right;
curr->data = tmp->data;
curr->right = tmp->right;
delete tmp;
}

}
return;
}

void BinarySearchTree::print_inorder()
{
inorder(root);
}

void BinarySearchTree::inorder(tree_node* p)
{
if(p != NULL)
{
if(p->left) inorder(p->left);
cout<<" "<<p->data<<" ";
if(p->right) inorder(p->right);
}
else return;
}

void BinarySearchTree::print_preorder()
{
preorder(root);
}

void BinarySearchTree::preorder(tree_node* p)
{
if(p != NULL)
{
cout<<" "<<p->data<<" ";
if(p->left) preorder(p->left);
if(p->right) preorder(p->right);
}
else return;
}
37

void BinarySearchTree::print_postorder()
{
postorder(root);
}

void BinarySearchTree::postorder(tree_node* p)
{
if(p != NULL)
{
if(p->left) postorder(p->left);
if(p->right) postorder(p->right);
cout<<" "<<p->data<<" ";
}
else return;
}

int main()
{
BinarySearchTree b;
int ch,tmp,tmp1;
while(1)
{
cout<<endl<<endl;
cout<<" Binary Search Tree Operations "<<endl;
cout<<" ----------------------------- "<<endl;
cout<<" 1. Insertion/Creation "<<endl;
cout<<" 2. In-Order Traversal "<<endl;
cout<<" 3. Pre-Order Traversal "<<endl;
cout<<" 4. Post-Order Traversal "<<endl;
cout<<" 5. Removal "<<endl;
cout<<" 6. Exit "<<endl;
cout<<" Enter your choice : ";
cin>>ch;
switch(ch)
{
case 1 : cout<<" Enter Number to be inserted : ";
cin>>tmp;
b.insert(tmp);
break;
case 2 : cout<<endl;
cout<<" In-Order Traversal "<<endl;
cout<<" -------------------"<<endl;
b.print_inorder();
break;
case 3 : cout<<endl;
cout<<" Pre-Order Traversal "<<endl;
cout<<" -------------------"<<endl;
b.print_preorder();
break;
case 4 : cout<<endl;
cout<<" Post-Order Traversal "<<endl;
cout<<" --------------------"<<endl;
b.print_postorder();
break;
case 5 : cout<<" Enter data to be deleted : ";
cin>>tmp1;
b.remove(tmp1);
break;
case 6 : system("pause");
38

return 0;
break;
}
}
}
39

Output:

Binary Search Tree Operations


-----------------------------
1. Insertion/Creation
2. In-Order Traversal
3. Pre-Order Traversal
4. Post-Order Traversal
5. Removal
6. Exit
Enter your choice: 1
Enter the element to be inserted: 4

Binary Search Tree Operations


-----------------------------
1. Insertion/Creation
2. In-Order Traversal
3. Pre-Order Traversal
4. Post-Order Traversal
5. Removal
6. Exit
Enter your choice: 1
Enter the element to be inserted: 6

Binary Search Tree Operations


-----------------------------
1. Insertion/Creation
2. In-Order Traversal
3. Pre-Order Traversal
4. Post-Order Traversal
5. Removal
6. Exit
Enter your choice: 1
Enter the element to be inserted:8

Binary Search Tree Operations


-----------------------------
1. Insertion/Creation
2. In-Order Traversal
3. Pre-Order Traversal
4. Post-Order Traversal
5. Removal
6. Exit
Enter your choice: 2
In-order traversal : 4 6 8
Binary Search Tree Operations
-----------------------------
1. Insertion/Creation
2. In-Order Traversal
3. Pre-Order Traversal
4. Post-Order Traversal
5. Removal
6. Exit
Enter your choice:3
Pre-order traversal: 6 4 8

Week-6
40

AIM: To write C++ programs that use non-recursive functions to traverse the given
binary
tree in a) Preorder b) Inorder and c) Postorder.

Implemention:

#include<iostream.h>
#include<conio.h>
#include<stdlib.h>

class binarynode
{
public:
int data;
binarynode *left;
binarynode *right;
};

class binsrctree
{
private:
binarynode *root;
void inorder(binarynode *);
void preorder(binarynode *);
void postorder(binarynode *);
public:
binsrctree()
{
root=NULL;
}
void insert(int );
void print_inorder();
void print_preorder();
void print_postorder();
};

class stack
{
int top;
binarynode *stackel[20];
public:
stack()
{
top=-1;
}
void push(binarynode *);
binarynode* pop();
int empty()
{
if(top==-1)
return(1);

return(0);
}
};

void stack::push(binarynode *node)


{
stackel[++top]=node;
}
41

binarynode *stack::pop()
{
return(stackel[top--]);
}

class stack_int
{
int top;
int stack_int[20];
public:
stack_int()
{
top=-1;
}
void push(int flag);
int pop();
int empty_int()
{
if(top==-1)
return(1);

return(0);
}
};

void stack_int::push(int flag)


{
stack_int[++top]=flag;
}

int stack_int::pop()
{
return(stack_int[top--]);
}
/*---------------------------------------------------------------------*/
/* FUNCTION TO INSERT A NODE IN THE TREE */
/*---------------------------------------------------------------------*/
void binsrctree::insert(int val)
{
binarynode *temp,*prev,*curr;
temp=new binarynode;
temp->data=val;
temp->left=temp->right=NULL;

if(root==NULL)
{
root=temp;
}
else
{
curr=root;
while(curr!=NULL)
{
prev=curr;
if(temp->data<curr->data)
curr=curr->left;
else
curr=curr->right;
}
42

if(temp->data<prev->data)
prev->left=temp;
else
prev->right=temp;
}
}

/*--------------------------------------------------*/
/*INORDER NON RECURSIVE TRAVERSAL*/
/*--------------------------------------------------*/

void binsrctree::inorder(binarynode *root)


{
stack stk;
binarynode *temp;
if(root!=NULL)
{
temp=root;
do
{
while(temp!=NULL)
{
stk.push(temp);
temp=temp->left;
}/*end while*/
if(!stk.empty())
{
temp=stk.pop();
cout<<temp->data<<" ";
temp=temp->right;
}/*end if*/
else
break;
}while(1); /*end do while*/
}/* end if */
else
cout<<"Empty tree";

} /*end function */

/*--------------------------------------------------*/
/*PREORDER NON RECURSIVE TRAVERSAL */
/*---------------------------------------------------*/

void binsrctree::preorder(binarynode *root)


{
stack stk;
binarynode *temp=root;
stk.push(temp);
while(!stk.empty())
{
temp=stk.pop();
if(temp!=NULL)
{
cout<<temp->data<<" ";
stk.push(temp->right);
stk.push(temp->left);
}
43

/*--------------------------------------------------*/
/*POSTORDER NON RECURSIVE TRAVERSAL */
/*---------------------------------------------------*/

void binsrctree::postorder(binarynode *root)


{
stack stk;
stack_int stk1;
int flag;
binarynode *temp=root;

do
{
if(temp!=NULL)
{
stk.push(temp);
stk1.push(1);
temp=temp->left;
}
else
{
if(stk.empty())
break;
temp=stk.pop();
flag=stk1.pop();
if(flag==2)
{
cout<<temp->data;
temp=NULL;
} /*end if */
else
{
stk.push(temp);
stk1.push(2);
temp=temp->right;
} /* end else */
} /* end if */
}while(1);/*end do while*/
}/*end function*/

/*--------------------------------------------------*/
/*FUNCTION TO PRINT INORDER NON RECURSIVE TRAVERSAL */
/*---------------------------------------------------*/

void binsrctree::print_inorder()
{
cout<<" ";
inorder(root);
cout<<" ";
}

/*--------------------------------------------------*/
/*FUNCTION TO PRINT PREORDER NON RECURSIVE TRAVERSAL */
44

/*---------------------------------------------------*/

void binsrctree::print_preorder()
{
cout<<" ";
preorder(root);
cout<<" ";
}

/*--------------------------------------------------*/
/*FUNCTION TO PRINT POSTORDER NON RECURSIVE TRAVERSAL */
/*---------------------------------------------------*/

void binsrctree::print_postorder()
{
cout<<" ";
postorder(root);
cout<<" ";
}

/*--------------------------------------------------*/
/* MAIN FUNCTION */
/*---------------------------------------------------*/

void main()
{
binsrctree BST;
int ch,element;
clrscr();

do
{
cout<<"1. Insert a node in binary tree";
cout<<"2. Inorder traversal";
cout<<"3.preorder traversal";
cout<<"4. postorder traversal";
cout<<"5. Exit \nEnter your choice";
cin>>ch;

switch(ch)
{
case 1: cout<<"Enter the element you want to insert";
cin>>element;
BST.insert(element);
break;
case 2: cout<<"Inorder traversal";
BST.print_inorder();
break;
case 3: cout<<preorder traversal";
BST.print_preorder();
break;
case 4: cout<<"postorder traversal";
BST.print_postorder();
break;
case 5:exit(1);
}
}while(ch!=5);
}
Output:
45

1. Insert a node in binary tree


2. Inorder traversal
3. Preorder traversal
4. Postorder traversal
5. Exit
Enter your choice:1
Enter the element to be inserted: 4

1. Insert a node in binary tree


2. Inorder traversal
3. Preorder traversal
4. Postorder traversal
5. Exit
Enter your choice:1
Enter the element to be inserted: 5

1. Insert a node in binary tree


2. Inorder traversal
3. Preorder traversal
4. Postorder traversal
5. Exit
Enter your choice:1
Enter the element to be inserted: 6

1. Insert a node in binary tree";


2. Inorder traversal
3. Preorder traversal
4. Postorder traversal
5. Exit
Enter your choice:3
Preorder traversal
5 4 6

Week -7

AIM: To write C++ programs for the implementation of BFS and DFS for a given
graph.

Description:

GRAPHS
A graph can be thought of a collection of vertices (V) and edges (E), so we
write,
G = (V, E)

Graphs can be directed, or undirected, weighted or unweighted.


A directed graph, or digraph, is a graph where the edge set is an ordered pair.
That is, edge 1 being connected to edge 2 does not imply that edge 2 is
connected to edge 1. (i.e. it has direction trees are special kinds of directed
graphs)
An undirected graph is a graph where the edge set in an unordered pair.
That is, edge 1 being connected to edge 2 does imply that edge 2 is connected
to edge 1.
A weighted graph is graph which has a value associated with each edge. This
can be a distance, or cost, or some other numeric value associated with the
edge.
46

Breadth First Search and Traversal


In Breadth first search we start at vertex v and mark it as having been reached
(visited) the vertex v is at this time said to be unexplored. A vertex is said to have
been explored by an algorithm when the algorithm has visited all vertices adjacent
from it. All unvisited vertices adjacent from v are visited next. These are new
unexplored vertices. Vertex v has now been explored. The newly visited vertices have
not been explored and or put on to the end of a list of unexplored list of vertices. The
first vertex on this list is the next to be explored. Exploration continues until no
unexplored vertex is left. The list of unexplored vertices operates as a queue and can
be represented using any of the standard queue representations.

Algorithm BFS(v)
//A breadth first search of G is carried out beginning at vertex v. For
//any node I, visited[I=1 if I has already been visited. The graph G
//and array visited are global; visited[] is initialized to zero.
{
u:=v; //q is a queue of unexplored vertices
visited[v]:=1;
repeat
{
for all vertices w adjacent from u do
{
if (visited[w]=0) then
{
add w to q; //w is unexplored
visited[w]:=1;
}
}
if q is empty then return; //no unexplored vertex
delete u from q; //get first unexplored vertex
}until(false);
}

Algorithm BFT(G, n)
//Breadth first traversal of G
{
for I:=1 to n do //mark all vertices unvisited
visited[I]:=0;
for I:=1 to n do
if (visited[I]=0) then
BFS(i);
}
47

Depth First Search and Traversal


A depth first search of a graph differs from a breadth first search in that the
exploration of a vertex v is suspended as soon as a new vertex is reached. At this time
of exploration of the new vertex u begins. When this new vertex has been explored,
the exploration of v continues. The search terminates when all reached vertices have
been fully explored. The search process is best described recursively in the following
algorithm

Algorithm:

In this all of nodes descendents are visited before we move to an adjacent nodes. The
adjacent
nodes are processed using LIFO.
1. Traversal starts at A. Push it into stack.
2. When we loop and pop the stack after processing the vertex , push all the
adjacent vertices into the stack .
3. To process B at step-2 we push onto the stack C,D,E before processing
either G (or)F .
4. If when the stack is empty , the traversal is completed .

Implementation:

#include<conio.h>
#include<iostream.h>
#include<stdlib.h>

void create(); // For creating a graph


void dfs(); // For Deapth First Search(DFS) Traversal.
void bfs(); // For Breadth First Search(BFS) Traversal.

struct node // Structure for elements in the graph


{
int data,status;
struct node *next;
struct link *adj;
};

struct link // Structure for adjacency list


{
struct node *next;
struct link *adj;
};

struct node *start,*p,*q;


struct link *l,*k;

int main()
{
int choice;
clrscr();
create();
while(1)
{
cout<<" -----------------------";
cout<<"1: DFS 2: BSF 3: Exit Enter your choice: ";
cin>>choice;
switch(choice)
{
case 1:
48

dfs();
break;
case 2:
bfs();
break;
case 3:
exit(0);
break;
default:
cout<<"Incorrect choice!Re-enter your choice.";
getch();
}
}
return 0;
}

void create() // Creating a graph


{
int dat,flag=0;
start=NULL;
cout<<"Enter the nodes in the graph(0 to end): ";
while(1)
{
cin>>dat;
if(dat==0)
break;
p=new node;
p->data=dat;
p->status=0;
p->next=NULL;
p->adj=NULL;
if(flag==0)
{
start=p;
q=p;
flag++;
}
else
{
q->next=p;
q=p;
}
}
p=start;

while(p!=NULL)
{
cout<<"Enter the links to "<<p->data<<" (0 to end) : ";
flag=0;
while(1)
{
cin>>dat;
if(dat==0)
break;
k=new link;
k->adj=NULL;
if(flag==0)
{
p->adj=k;
l=k;
49

flag++;
}
else
{
l->adj=k;
l=k;
}
q=start;
while(q!=NULL)
{
if(q->data==dat)
k->next=q;
q=q->next;
}
}
p=p->next;
}
cout<<"-------------------------";
return;
}

// Deapth First Search(DFS) Traversal.


void bfs()
{
int qu[20],i=1,j=0;
p=start;
while(p!=NULL)
{
p->status=0;
p=p->next;
}
p=start;
qu[0]=p->data;
p->status=1;
while(1)
{
if(qu[j]==0)
break;
p=start;
while(p!=NULL)
{
if(p->data==qu[j])
break;
p=p->next;
}
k=p->adj;
while(k!=NULL)
{
q=k->next;
if(q->status==0)
{
qu[i]=q->data;
q->status=1;
qu[i+1]=0;
i++;
}
k=k->adj;
}
j++;
}
50

j=0;
cout<<"Breadth First Search Results";
cout<<" --------------------------- ";
while(qu[j]!=0)
{
cout<<qu[j]<<" ";
j++;
}
getch();
return;
}

// Breadth First Search(BFS) Traversal.


void dfs()
{
int stack[25],top=1;
cout<<" Deapth First Search Results ";
cout<<"--------------------------- ";
p=start;
while(p!=NULL)
{
p->status=0;
p=p->next;
}
p=start;
stack[0]=0;
stack[top]=p->data;
p->status=1;
while(1)
{
if(stack[top]==0)
break;
p=start;
while(p!=NULL)
{
if(p->data==stack[top])
break;
p=p->next;
}
cout<<stack[top]<<" ";
top--;
k=p->adj;
while(k!=NULL)
{
q=k->next;
if(q->status==0)
{
top++;
stack[top]=q->data;
q->status=1;
}
k=k->adj;
}
}
getch();
return;
}
51

Output:

1: DFS
2: BSF
3: Exit Enter your choice:
Enter the nodes in the graph(0 to end): 5 4 6 8 7 9
Breadth First Search Results
4 6 7 8 9 5
52

Week -8

AIM: To write C++ programs for implementing the following sorting methods:
a) Quick sort b) Merge sort c) Heap sort

Implementation:

#include<iostream.h>
#include<conio.h>
#include<process.h>
template<class T>
class sort
{
private: int a;
public: sort(){int a=new int[50];}
sort(int n)
{
int a=new int[n];
}
void create();
void heapsort();

void display();
void mergesort();
void adjust(int [],int,int);
void swap(int a,int b);
void print(int [],int);
void merge(int [],int,int);
};

template<class T>
void sort<T>::create()
{
cout<<"\n Enter the elements";
for(int i=0;i<5;i++)
cin>>a[i];
}

template<class T>
void sort<T>::heapsort()
{
int i,n;
cout<<"\n The adjusted List:";
for(i=(n-1)/2;i>=0;i--)
adjust(a,i,n);
for(i=n-1;i>=0;i--)
{
swap(&a[i+1],&a[0]);
adjust(a,0,i);
}
}

template<class T>
void sort<T>::adjust(int &a[],int i,int n)
{
int flag=0,j,k;
k=a[i];
j=2*i+1;
while((j<=n)&&!flag)
53

{
if((j<n)&&a[j]<a[j+1])
j++;
if(k>=a[j])
{
flag=1;
}
else
{
a[j-1/2]=a[j];
j=s*j+1;
}
}
a[(j-1)/2]=k;
}

template<class T>
void sort<T>::swap(int *p,int *q)
{
int i;
t=*p;
*p=*q;
*q=*t;
}

template<class T>
void sort<T>::print()
{
int i;
for(i=0;i<n;i++)
cout<<a[i]<<"";
}

template<class T>
void sort<T>::mergesort()
{
int mid;
msort(int a[],int low,int high);
}

template<class T>
void sort<T>::msort(int a[],int low,int high)
{
int mid;
if(low<high)
{
mid=(high+low)/2;
msort(a,low,mid);
msort(a,mid+1,high);
}
}

template<class T>
void sort<T>::merge(int a[],int &m,int &n)
{
int b[5];
int i,j,k;
i=1;
j=m+1;
k=1;
54

while((i<=m)&&(j<=n))
{
if(a[i]<=a[j])
b[k++]=a[i++];
else
b[k++]=a[j++];
}
while(i<=n)
{
b[k++]=a[i++];
}
while(j<=n)
b[k++]=a[j++];
for(k=1;k<=n;k++)
a[k]=b[k];
}

void main()
{
int c;
sort<T> s;
do
{
s.create();
cout<<"\n ** Menu **";
cout<<"\n 1. Create 2. Quick sort 3:Mergesort 4. Heap sort 5:exit";
cin>>c;
swith(c)
{
case 1:s.create();
break;
case 2: s.quicksort();
break;
case 3:s.mergesort();
break;
case 4:s.heapsort();
break;
case 5:exit(0);
default: cout<<"\n Invalid choice";
}
}
while(c!=4);
}

Output:
** Menu **
1. Create
2. Quick sort
3. Mergesort
4. Heap sort
5.exit
Enter your choice: 1
Enter the elements
524 8 7
** Menu **
1. Create
2. Quick sort
3. Mergesort
4. Heap sort
5.exit
55

Enter your choice: 2


2457 8

** Menu **
1. Create
2. Quick sort
3. Mergesort
4. Heap sort
5. exit
Enter your choice: 3
2457 8
56

Week- 9

AIM: To write a C++ program to perform the following operations


a) Insertion into a B-tree
b) Deletion from a B-tree

Description:

B-Trees
An m-way tree in which

The root has at least one key


Non-root nodes have at least m/2 subtrees (i.e., at least (m - 1)/2 keys)
All the empty subtrees (i.e., external nodes) are at the same level

B-tree of order 3 not a B-tree

B-trees are especially useful for trees stored on disks, since their height, and hence
also the number of disk accesses, can be kept small.

The growth and contraction of m-way search trees occur at the leaves. On the other
hand, B-trees grow and contract at the root.

Insertions

Insert the key to a leaf


Overfilled nodes should send the middle key to their parent, and split into two
at the location of the submitted key.
57

add 19

add 21
58

Deletions

Key that is to be removed from a node with non-empty subtrees is being


replaced with the largest key of the left subtree or the smallest key in the right
subtree. (The replacement is guaranteed to come from a leaf.)

remove 26
59

If a node becomes under staffed, it looks for a sibling with an extra key. If such
a sibling exist, the node takes a key from the parent, and the parent gets the
extra key from the sibling.

remove 22
60

If a node becomes under staffed, and it cant receive a key from a sibling, the
node is merged with a sibling and a key from the parent is moved down to the
node.

remove 18
61
62

Implementation:

#include <iostream.h>
#include <conio.h>
class btre
{
struct node
{
node *left;
char data;
node *right;
}*root;
char *a;
int *lc,
int *rc;
public:
btre(char *,int *l,int *r,int size);
void insert(int index);
static node *create(char *a1,int *l,int *r,int index);
void display();
static void inorder(node *sr);
~btre();
static void del(node *sr);
};

btre::btre(char *a1,int *l,int *r,int size)


{
root=NULL;
a=new char[size];
lc=new int[size];
rc=new int[size];
for(int i=0;i<size;i++)
{
*(a1+i)=*(a1+i);
*(lc+i)=*(l+i);
*(rc+i)=*(r+i);
}
}

void btre::insert(int index)


{
root=create(a,lc,rc,index);
}

node *btre::create(char *a1,int *l,int *r,int index)


{
node *temp=NULL;
if(index!=-1)
{
temp=new node;
temp->left=create(a1,l,r,*(l+index));
temp->data=*(a1+index);
temp->right=create(a1,l,r,*(r+index));
}
return temp;
}
void btre::display()
{
inorder(root);
63

void btre::inorder(node *sr)


{
if(sr!=NULL)
{
inorder(sr->left);
cout<<sr->data<<"\t";
inorder(sr->right);
}
}

btre::~btre()
{
delete a;
delete lc;
delete rc;
del(root);
}

void btre::del(node *sr)


{
if(sr!=NULL)
{
del(sr->left);
del(sr->right);
}
delete sr;
}

void main()
{
char a1[15];
int l[15];
int r[15];
int sz;
clrscr();
cout<< "enter the size\n";
cin>>sz;
int sz1=sizeof(sz);
cout<<"enter the elements \n";
for(int i=0;i<sz1;i++)
{
cin>>a1[i];}
btre bt(a1,l,r,sz);
bt.insert(0);
cout<<"\n in-order traversal : "<<endl;
bt.display();
getch();
}

OUTPUT:
Enter size of the tree
6
enter elements
12
56
232
45
64

56
67
78
B tree before deletion
12 45 56 56 67 78 232
enter deleting element
67
Binary tree after delete
12 45 56 56 78 232
do you want delete?
65

Week -10

AIM: To write a C++ program to perform the following operation


a) Insertion into an AVL - tree
b) Deletion from an AVL tree

Description:
AVL Trees
An AVL tree (also called an "admissible tree") is a tree in which the height of the left
and right subtrees of every node differ by at most one - referred to as "height-
balanced".

Example AVL trees:


3 6 5
/\ /\ / \
2 5 4 7 2 9
/ /\ / \
3 1 4 7 12
/ \ /\
3 8 11 14
/
10
Example non-AVL trees:

5 6 5
/ / \ / \
3 3 10 2 9
/ /\ / /\ /\
2 1 4 7 1 4 7 12
\ / /\
8 3 11 14
/
10
In order to indicate the differences between the heights of the right and left subtrees of
a given (root) node, a balance factor is defined for that node of the subtree.

We define the balance factor, BF:


BF = (height of right subtree - height of left subtree)
So, BF = -1, 0 or +1 for an AVL tree.
Balance factors for example AVL trees (node key values not shown):
0 -1 +1
/\ / \ / \
0 0 -1 0 -1 -1
/ / / \
0 0 +1 0
\
0
When the AVL property is lost we can rebalance the tree via one of four rotations:

Single Right Rotation (SRR):

A is the node that the rotation is performed on. This rotation is performed when A is
unbalanced to the left (the left subtree is 2 higher than the right subtree) and B is left-
heavy (the left subtree of B is 1 higher than the right subtree of B). T1, T2 and T3
represent subtrees (a node was added to T1 which made B leftheavy and unbalanced
A).
A SRR at A B
/\ ----------> /\
66

B T3 T1 A
/\ /\
T1 T2 T2 T3

Single Left Rotation (SLR):

A is the node that the rotation is performed on. This rotation is performed when A is
unbalanced to the right (the right subtree is 2 higher than the left subtree) and B is
right-heavy (the right subtree of B is 1 higher than the left subtree of B). T1, T2 and
T3 represent subtrees (a node was added to T3 which made B right-heavy and
unbalanced A).

A SLR at A B

/\ ----------> /\
T1 B A T3
/\ /\
T2 T3 T1 T2

Double Left Rotation (DLR):

C is the node that the rotation is performed on. This rotation is performed when C is
unbalanced to the left (the left subtree is 2 higher than the right subtree), A is right-
heavy (the right subtree of A is 1 higher than the left subtree of A) and B is left-heavy.
T1, T2, T3, and T4 represent subtrees (a node was added to T2 which made B left-
heavy, made A right-heavy and unbalanced C). This consists of a single left rotation at
node A, followed by a single right at node C.

C SLR at A C SRR at C B
/\ ----------> / \ ---------> / \
A T4 B T4 A C
/\ /\ /\ /\
T1 B A T3 T1 T2 T3 T4
/\ /\
T2 T3 T1 T2
That is, DLR equiv SLR + SRR

Double Right Rotation (DRR):

A is the node that the rotation is performed on. This rotation is performed when A is
unbalanced to the right (the right subtree is 2 higher than the left subtree), C is
leftheavy (the left subtree of C is 1 higher than the right subtree of C) and B is right-
heavy. T1, T2, T3, and T4 represent subtrees (a node was added to T3 which made B
right-heavy, made C left-heavy and unbalanced A). This consists of a single right at
node C, followed by a single left at node A.

A SRR at C A SLR at A B

/\ ----------> / \ ----------> / \
T1 C T1 B A C
/\ /\ /\ /\
B T4 T2 C T1 T2 T3 T4
/\ /\
T2 T3 T3 T4
67

That is, DRR equiv SRR + SLR

Insertion in a AVL-tree
An AVL tree may become out of balance in two basic situations:

1. After inserting a node in the right subtree of the right child.


2. After inserting a node in the left subtree of the right child.
Insertion of a node in the right subtree of the right child:

This involves a SLR about node P:

Insertion of a node in the left subtree of the right child:

This involves a DRR:

In each case the tree is rebalanced locally (since there is no need to modify the
balance factors higher in the tree).
Since rebalancing is local, insertion requires one single or one double rotation, ie
O(constant) for rebalancing.
Of course, there is still the cost of search for insertion (see below).
Experiments have shown that 53% of insertions do not bring the tree out of balance.
Example: Given the following AVL tree, insert the node with value 9:
6
/ \
3 12
\ / \
4 7 13
\
10

Insertion into an AVL tree may be carried out by inserting the given value into the tree
as if it were an unbalanced binary search tree, and then retracing one's steps toward
the root, rotating about any nodes which have become unbalanced during the
insertion.
68

Deletion
Deletion from an AVL tree may be carried out by rotating the node to be deleted down
into a leaf node, and then pruning off that leaf node directly. Since at most log n nodes
are rotated during the rotation into the leaf, and each AVL rotation takes constant
time, the deletion process in total takes O(log n) time.

Implementation:

# include <iostream.h>
# include <stdlib.h>
# include <conio.h>

struct node
{
int element;
node *left;
node *right;
int height;
};

typedef struct node *nodeptr;

class bstree
{

public:
void insert(int,nodeptr &);
void del(int, nodeptr &);
int deletemin(nodeptr &);
void find(int,nodeptr &);
nodeptr findmin(nodeptr);
nodeptr findmax(nodeptr);
void copy(nodeptr &,nodeptr &);
void makeempty(nodeptr &);
nodeptr nodecopy(nodeptr &);
void preorder(nodeptr);
void inorder(nodeptr);
void postorder(nodeptr);
int bsheight(nodeptr);
nodeptr srl(nodeptr &);
nodeptr drl(nodeptr &);
nodeptr srr(nodeptr &);
nodeptr drr(nodeptr &);
int max(int,int);
int nonodes(nodeptr);
};

//Inserting a node
void bstree::insert(int x,nodeptr &p)
{
if (p == NULL)
{
p = new node;
p->element = x;
p->left=NULL;
p->right = NULL;
p->height=0;
if (p==NULL)
69

cout<<"Out of Space";
}
else
{
if (x<p->element)
{
insert(x,p->left);
if ((bsheight(p->left) - bsheight(p->right))==2)
{
if (x < p->left->element)
p=srl(p);
else
p = drl(p);
}
}
else if (x>p->element)
{
insert(x,p->right);
if ((bsheight(p->right) - bsheight(p->left))==2)
{
if (x > p->right->element)
p=srr(p);
else
p = drr(p);
}
}
else
cout<<"Element Exists";
}
int m,n,d;
m=bsheight(p->left);
n=bsheight(p->right);
d=max(m,n);
p->height = d + 1;

// Finding the Smallest


nodeptr bstree::findmin(nodeptr p)
{
if (p==NULL)
{
cout<<"Empty Tree";
return p;
}
else
{
while(p->left !=NULL)
p=p->left;
return p;
}
}

// Finding the Largest


nodeptr bstree::findmax(nodeptr p)
{
if (p==NULL)
{
cout<<"Empty Tree";
return p;
70

}
else
{
while(p->right !=NULL)
p=p->right;
return p;
}
}

// Finding an element
void bstree::find(int x,nodeptr &p)
{
if (p==NULL)
cout<<"Element not found";
else
if (x < p->element)
find(x,p->left);
else
if (x>p->element)
find(x,p->right);
else
cout<<"Element found !";

// Copy a tree
void bstree::copy(nodeptr &p,nodeptr &p1)
{
makeempty(p1);
p1 = nodecopy(p);
}

// Make a tree empty


void bstree::makeempty(nodeptr &p)
{
nodeptr d;
if (p != NULL)
{
makeempty(p->left);
makeempty(p->right);
d=p;
free(d);
p=NULL;
}
}

// Copy the nodes


nodeptr bstree::nodecopy(nodeptr &p)
{
nodeptr temp;
if (p==NULL)
return p;
else
{
temp = new node;
temp->element = p->element;
temp->left = nodecopy(p->left);
temp->right = nodecopy(p->right);
return temp;
}
71

// Deleting a node
void bstree::del(int x,nodeptr &p)
{
nodeptr d;
if (p==NULL)
cout<<"Element not found";
else if ( x < p->element)
del(x,p->left);
else if (x > p->element)
del(x,p->right);
else if ((p->left == NULL) && (p->right == NULL))
{
d=p;
free(d);
p=NULL;
cout<<" Element deleted !";
}
else if (p->left == NULL)
{
d=p;
free(d);
p=p->right;
cout<<" Element deleted !";
}
else if (p->right == NULL)
{
d=p;
p=p->left;
free(d);
cout<<" Element deleted !";
}
else
p->element = deletemin(p->right);
}

int bstree::deletemin(nodeptr &p)


{
int c;
cout<<"inside deltemin ";
if (p->left == NULL)
{
c=p->element;
p=p->right;
return c;
}
else
{
c=deletemin(p->left);
return c;
}
}

void bstree::preorder(nodeptr p)
{
if (p!=NULL)
{
cout<<p->element<<"-->";
preorder(p->left);
72

preorder(p->right);
}
}

// Inorder Printing
void bstree::inorder(nodeptr p)
{
if (p!=NULL)
{
inorder(p->left);
cout<<p->element<<"-->";
inorder(p->right);
}
}

// PostOrder Printing
void bstree::postorder(nodeptr p)
{
if (p!=NULL)
{
postorder(p->left);
postorder(p->right);
cout<<p->element<<"-->";
}
}

int bstree::max(int value1, int value2)


{
return ((value1 > value2) ? value1 : value2);
}

int bstree::bsheight(nodeptr p)
{
int t;
if (p == NULL)
return -1;
else
{
t = p->height;
return t;
}
}

nodeptr bstree:: srl(nodeptr &p1)


{
nodeptr p2;
p2 = p1->left;
p1->left = p2->right;
p2->right = p1;
p1->height = max(bsheight(p1->left),bsheight(p1->right)) + 1;
p2->height = max(bsheight(p2->left),p1->height) + 1;
return p2;
}

nodeptr bstree:: srr(nodeptr &p1)


{
nodeptr p2;
p2 = p1->right;
p1->right = p2->left;
p2->left = p1;
73

p1->height = max(bsheight(p1->left),bsheight(p1->right)) + 1;
p2->height = max(p1->height,bsheight(p2->right)) + 1;
return p2;
}

nodeptr bstree:: drl(nodeptr &p1)


{
p1->left=srr(p1->left);
return srl(p1);
}

nodeptr bstree::drr(nodeptr &p1)


{
p1->right = srl(p1->right);
return srr(p1);
}

int bstree::nonodes(nodeptr p)
{
int count=0;
if (p!=NULL)
{
nonodes(p->left);
nonodes(p->right);
count++;
}
return count;

int main()
{
clrscr();
nodeptr root,root1,min,max;//,flag;
int a,choice,findele,delele,leftele,rightele,flag;
char ch='y';
bstree bst;
//system("clear");
root = NULL;
root1=NULL;
cout<<"AVL Tree";
cout<<"========";
do
{
cout<<"1.Insertion 2.FindMin 3.FindMax;
cout<<4.Find 5.Copy 6.Delete 7.Preorder;
cout<<8.Inorder 9.Postorder 10.height ";
cout<<"Enter the choice:";
cin>>choice;
switch(choice)
{
case 1: cout<<"New node's value ?";
cin>>a;
bst.insert(a,root);
break;
case 2: if (root !=NULL)
{
74

min=bst.findmin(root);
cout<<"Min element :"<<min->element;
}
break;
case 3: if (root !=NULL)
{
max=bst.findmax(root);
cout<<"Max element :"<<max->element;
}
break;
case 4: cout<<"Search node : ";
cin>>findele;
if (root != NULL)
bst.find(findele,root);
break;
case 5: bst.copy(root,root1);
bst.inorder(root1);
break;
case 6: cout<<"Delete Node ?";
cin>>delele;
bst.del(delele,root);
bst.inorder(root);
break;

case 7: cout<<"Preorder Printing... :";


bst.preorder(root);
break;

case 8: cout<<" Inorder Printing.... :";


bst.inorder(root);
break;

case 9: cout<<" Postorder Printing... :";


bst.postorder(root);
break;
case 10: cout<<"Height and Depth is ";
cout<<bst.bsheight(root);
cout<<"No. of nodes:- "<<bst.nonodes(root);
break;

}
cout<<"Do u want to continue (y/n) ?";
cin>>ch;
}while(ch=='y');

return 0;
}

Output:

1.Insertion
2.FindMin
3.FindMax
4.Find
5.Copy
6.Delete
7.Preorder
8.Inorder
75

9.Postorder
10.height
Enter the choice:1
New nodes value: 34

1.Insertion
2.FindMin
3.FindMax
4.Find
5.Copy
6.Delete
7.Preorder
8.Inorder
9.Postorder
10.height
Enter the choice:1
New nodes value: 43

1.Insertion
2.FindMin
3.FindMax
4.Find
5.Copy
6.Delete
7.Preorder
8.Inorder
9.Postorder
10.height
Enter the choice:1
New nodes value: 54
76

Week- 11

AIM: To write a C++ program to implement All Pairs Shortest Path.

Description:

If we want to find the shortest distance between any two nodes in a graph, we can:
1. run Bellman-Ford algorithm (or any other single-source shortest paths algorithm)
using each node as the source
2. invent some other algorithm.

Simple ideas:

What is in the weight matrix? The shortest paths consisting of one edge.

How do we get the shortest paths consisting of, say, two edges?

For example, we have the following graph.

a b c d

O 5 10 3

W= X O 1 -4

X X O X

X X 2 O

We have to think about what we want to put in places of O and X. X means no


connection and O means no self loop.
There is a path from a to c of weight 10. But, if we allow paths of 2 edges, then there
is a shorter path adc, and also abc. How do we get to find them using the W matrix?
So, the best path so far is the smallest path between ac, ab+bc, and ad+dc.

Idea: multiply the W matrix by itself. Instead of multiplication, use addition, and
instead of summing, use minimum between several values.

If we put 0 for O and infinity for X, then we will find shortest paths of at most two
edges. If we put infinity for both O and X, then we will find shortest paths of exactly
two edges, and then at the end we will still have to find the shortest path out of all
possible shortest paths of 1, 2, 3, ., n-1 edges. So, it is easier to do the work as we
are going along and find all shortest paths of at most m edges. So, we will use 0 for O
and infinity for X.
77

Then, how do we get the shortest path of at most three edges? For ac, now we have to
pick the minimum between ac, abc, adc, and abdc.

Lets formalize:

Regular all-pairs shortest paths

Main idea: keep on growing the adjacency matrix so that we find the shortest paths
of at most one edge, two edges, three edges, etc.

lij(m) represents the weight of the shortest path from node i to node j such that the
entire path contains at most m edges.

Solve by using modified matrix multiplication.


Regular matrix multiplication: C = ABcij = k=1, n (aik * bkj)

Shortest-path matrix multiplication: lij(m) = min (lij(m-1) + wkj)


1 k n

Exercise1: program the above formula as a dynamic programming solution.

Exercise2: also include pseudocode to reconstruct the shortest path.

Slow-n-sure way:
L(1) = W
L(2) = L(1) W
L(3) = L(2) W

L(n-1) = L(n-2) W

Faster way: Since L(s) = L(n-1) for all s n-1, we can skip all intermediate steps and
work by doubling the order of L.
L(1) = W
L(2) = W W
L(4) = L(2) L(2)
L(8) = L(4) L(4)

L(s) = L(s/2) L(s/2) for the first s such that s n-1 and lg s =k, where k I.
78

Floyd-Warshall Algorithm

(also to find all pairs of shortest paths)

Main idea: Split the path from vertex i to vertex j at an intermediate node k. Try all
possible ks and find k that gives the shortest path.

dij(k) represents the weight of the shortest path from node i to node j such that all
intermediate vertices in the path are in the set {1,2, 3, ,k}.

wij if k=0

dij(k) =

min (dij(k-1), dik(k-1) + dkj(k-1)) if 1 k n

Final solution: D(n).


Exercise: program the above formula as a dynamic programming solution.
We must also be able to reconstruct the path. Our textbook has a solution, and we
used yet another method in class.
The way of our textbook:
ij (0) = NIL, if i=j or wij =
= i, if ij or wij <

ij (k) = ij (k-1), if dij(k-1) dik(k-1) + dkj(k-1)


= kj (k-1)
, if dij(k-1) > dik(k-1) + dkj(k-1)
We used a slightly different method in class. Our method was based on the matrix
chain pseudocode. See if you can put it into pseudocode for this application. (Problem
25.2-7).

Algorithm :

let dist be a |V| |V| array of minimum distances initialized to (infinity)


for each vertex v
dist[v][v] 0
for each edge (u,v)
dist[u][v] w(u,v) // the weight of the edge (u,v)
for k from 1 to |V|
for i from 1 to |V|
for j from 1 to |V|
if dist[i][k] + dist[k][j] < dist[i][j] then
dist[i][j] dist[i][k] + dist[k][j]

Implementation:
79

#include<iostream>
#include<conio.h>
using namespace std;
int min(int a,int b);
int cost[10][10],a[10][10],i,j,k,c;
main()
{
int n,m;
cout <<"enter no of vertices";
cin >> n;
cout<<"enter no od edges";
cin >> m;
cout<<"enter the\nEDGE Cost\n";
for(k=1;k<=m;k++)
{
cin>>i>>j>>c;
a[i][j]=cost[i][j]=c;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(a[i][j]== 0 && i !=j)
a[i][j]=31999;
}
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
cout <<"Resultant adj matrix\n";
for(i=1;i<=n;i++)
{
for( j=1;j<=n;j++)
{
if(a[i][j] !=31999)
cout << a[i][j] <<" ";
}
cout <<"\n";
}
getch();
}

int min(int a,int b)


{
if(a<b) return a;
else return b;
}

Output:

Enter no of vertices 3
enter no od edges 5
enter the EDGE Cost 1 2 4 216 1 3 11 313 232
80

Resultant adj matrix 0 4 6


502
370
81

Week- 12

AIM: Write a C++ program for implementing 8 Queens problem.

Description:

The Problem
The 8-queens problem can be defined as follows: Place 8 queens on an (8 by 8) chess
board such that none of the queens attacks any of the others. A configuration of 8
queens on the board is shown in figure 1, but this does not represent a solution as the
queen in the first column is on the same diagonal as the queen in the last column.

We will briefly introduce solution by backtracking.


First lets explain what is backtracking? The board should be regarded as a set of
constraints and the solution is simply satisfying all constraints. For example: Q1
attacks some positions, therefore Q2 has to comply with these constraints and take
place, not directly attacked by Q1. Placing Q3 is harder, since we have to satisfy
constraints of Q1 and Q2. Going the same way we may reach point, where the
constraints make the placement of the next queen impossible. Therefore we need to
relax the constraints and find new solution. To do this we are going backwards and
finding new admissible solution. To keep everything in order we keep the simple rule:
last placed, first displaced.
In other words if we place successfully queen on the i th column but cannot find solution
for (i+1)th queen, then going backwards we will try to find other admissible solution for
the ith queen first. This process is called backtrack Lets discuss this with example. For
the purpose of this handout we will find solution of 4queen problem.

Algorithm:
- Start with one queen at the first column first row
- Continue with second queen from the second column first row
- Go up until find a permissible situation
- Continue with next queen
82

Implementation:

# include <iostream.h>
# include <stdlib.h>
# include <time.h>
int N; //For N * N ChessBoard
int flag;
void printArray(int a[]); /* Just to Print the Final Solution */
void getPositions(int a[],int n1,int n2); /* The Recursive Function */
int main()
{
int *a;
int ctr=0;
cout<<"\nTHE N QUEENS PROBLEM ";
cout<<"\nNumber Of Rows(N) For NxN Chessboard.";
cin>>N;
a=(int *)(malloc(sizeof(int)*N));
cout<<"\nAll possible Solutions .. \n";
cout<<"In Each of the solutions the Coordinates of the N-Queens are given
(Row,Col).";
cout<<"\nNote that the Rows and Colums are numbered between 1 - N :\n";
for(ctr=0;ctr<N;ctr++)
getPositions(a,0,ctr);
getchar();
getchar();
}

void printArray(int a[])


{
int i,choice;
static int counter=0;
counter++;
cout<<"\nSOLUTION:"<<counter;
for(i=0;i<N;i++)
cout<<(<<i+1<<a[i]+1<<);
if(counter%10==0)
{
Cout<<"\nEnter 0 to exit , 1 to continue .";
Cin>>choice;
if(choice==0) exit(0);
};
}

void getPositions(int a1[],int colno,int val)


{
int ctr1,ctr2;
a1[colno]=val;
if(colno==N-1)
{
printArray(a1) ; return;
};

for(ctr1=0;ctr1<N;)

{
/* This Loop Finds Suitable Column Numbers , in the NEXT ROW */
for(ctr2=0;ctr2<=colno;ctr2++)
if(a1[ctr2]==ctr1 || (colno+1-ctr2)*(colno+1-ctr2)==(ctr1-a1[ctr2])*(ctr1-
a1[ctr2]))
goto miss1;
83

getPositions(a1,colno+1,ctr1);
miss1:
ctr1++;
}
}

Input

The first line contains N, the numbers of queens that needs to be placed on the NxN
chessboard such that 1 <= N <= 8

Output

The chessboard with N queens placed such that no queen can kill the other.

The position where the Q is present should have Q printed, while the position where
there is no queen should have - printed, with each value being separated by a tab
or \t.

All possible solutions for the given value of N need to be printed. Each solution must be
separated by a blank line.

If No Solution is possible Print "Not Possible"

Example
Input:

1.
2

2.
4

Output:

1.Not Possible

2.
- Q - -
- - - Q
Q - - -
- - Q -

- - Q -
Q - - -
- - - Q
- Q - -
84

Experiments beyond the syllabus


85

13. AIM : To write a C++ program to implement circular queue ADT using an
array

CIRCULAR QUEUES

Removing an element from the queue is an expensive operation because all remaining
elements have to be moved by one position. A more efficient implementation is
obtained if we consider the array as being circular:

Implementation of circular queues using arrays

Algorithm Add!(item)
// insert item in the circular queue stored in q[0 : n-1].
//rear points to the last item, and front is one position
// counter clock wise from the first item in q.
{
rear := (rear + 1) mod n; // advance rear clock wise
if (front = rear) then
{
write (queue is full);
if (front=0) then rear:=n-1;
else rear:=rear-1;
//move rear one position counter clockwise.
return false.
}
else
{
q[rear]:=item;
return true
}
}
Algorithm DeleteQ()
// Removes and returns the front element of the queue q[0 : n-1].
{
if (front=rear) then
{
write (queue is empty);
return false;
}
else
{
front := (front +1) mod n // advance front clockwise
item := q[front];
return true;
}
}

Implementation:

#include<iostream.h>
86

#include<conio.h>
#include<process.h>
#define max 5
class CQ
{
int a[max];
public:
int front, rear;
CQ()
{
rear=front=-1;
}
void insert(),del(),display();
};
void CQ::insert()
{
if(((rear==max-1)&&(front==0))||(front==rear+1))
cout<<"CQ overflow";
else
{
int n;
cout<<"enter the element to insert";
cin>>n;
if(rear!=max-1)
{
a[++rear]=n;
if(front==-1)
front++;
}
else
{
rear=-1;
a[++rear]=n;
}
}
}

void CQ::del()
{
if(rear==-1)
cout<<"cq underflow";
else
{
cout<<"deleted element is"<<a[front++];
if(front==rear+1)
front=rear=-1;
if(front==max)
front=0;
}
cout<<endl;
}

void CQ::display()
{
int i;
if(rear==-1)
cout<<"cq empty";
else if(front<=rear)
for(i=front;i<=rear;i++)
cout<<"\t"<<a[i];
87

else {
for(i=front;i<=max-1;i++)
cout<<"\t"<<a[i];
for(i=0;i<=rear;i++)
cout<<"\t"<<a[i];
}
cout<<endl;
}

void main()
{
CQ q;
int ch,x;
do
{
cout<<"1.insert 2.delete 3.display 4.exit";
cout<<"enter ur choice";
cin>>ch;
switch(ch)
{
case 1: q.insert();
break;
case 2: q.del();
break;
case 3:q.display();
break;
case 4:exit(0);
}
} while(ch!=4);
}
88

14. AIM : To write a C++ program to implement all the functions of a dictionary
(ADT) using hashing.

Dictionary : A Dictionary is a collection of pairs of the form (K,V). where K is a Key


and
V is the value associated with the key k. No two pairs in the dictionary have a same
key.
The Following operations performed on a dictionary :
Determine whether or not the dictionary is empty
Determine the dictionary Size ( No of Pairs )
Find the pair with a specified key
Insert a pair into the dictionary
Delete or erase the pair into the specified key

ABSTRACT DATA TYPE :


INSTANCES : Collection of pairs with distinct keys
OPERATIONS :
Empty() : return true iff the dictionary is empty
Size() : return the no. of pairs in the dictionary
Find(k) : return the pair with the key , K.
Insert(p) : insert the pair P into the dictionary
Erase(k) : delete the pair with key K.

Implementation:
#include<iostream.h>
Class sll
{
private:
struct node
{
int key;
int value;
struct node *next;
}*head;
public:
sll();
~sll();
void insert();
void print();
void del();
int length();
};

sll::sll()
{
head=new node;
head=NULL; //initialize head to NULL
}

void sll::insert()
{
node *new,*curr,*prev;
int k,val;
new=new node;
cout<<endl<<Enter the record in the pair form: ;
cin>>k;
cin>>val;
new->key=k;
new->value=val;
89

if(head==NULL) //creating header node


{
head=new;
curr=head;
prev=curr;
}
else
{
curr=head;
prev=prev;
}
while((curr->key<new->key)&&(curr!=Null))
{
prev=curr;
curr=curr->next;
}
if((curr->next=NULL)
{
if(curr->key<new->key)
{
curr->next=new;
prev=curr;
}
else
{
new->next=prev->next;
}
}
}
else
{
new->next=prev->next;
prev->next=new;
}
}

int sll::length()
{
node *curr;
int count;
count=0;
curr=head;
if(curr==NULL)
{
cout<<endl<<List is empty;
return 0;
}
while(curr!=0)
{
count++;
curr=curr->next;
}
return 0;
}

void sll::print()
{
node *temp;
temp=head;
if(temp==NULL)
90

{
cout<<endl<<List is empty;
return 0;
}
while(temp!=NULL)
{
cout<<endl<<<<<temp->key<<<<temp->value<<>;
temp=temp->next;
}
}

void sll::del()
{
node *curr,*prev;
int k;
curr=head;
cout<<endl<<Enter the key value to be delete: ;
cin>>k;
while(curr!=NULL)
{
if(curr->key==k)
break;
prev=curr;
curr=curr->next;
}
if(curr==NULL)
cout<<endl<<Node not found;
else
{
if(curr==head)
head=curr->next;
else
prev->next=curr->next;
delete curr;
}
}

void main()
{
sll s;
int ch, int;
char ans=y;
do
{
cout<<endl<<****Menu****;
cout<<endl<<1.Insert;
cout<<endl<<2.Display;
cout<<endl<<3.Delete;
cout<<endl<<4.Length;
cout<<endl<<Enter your choice: ;
cin>>ch;
switch(ch)
{
case 1:
s.insert();
break;
case 2:
s.print();
break;
case 3:
91

s.del();
break;
case 4:
int=s.length();
cout<<int;
break;
}
cout<<endl<<int;
}while(ans=y);
return i;
}

OUTPUT :
****Menu****
1.Insert
2.Display
3.Delete
4.Length
Enter your choice: 1
Enter the key & value : <2,34>
****Menu****
1.Insert
2.Display
3.Delete
4.Length
****Menu****
1.Insert
2.Display
3.Delete
4.Length
Enter your choice : 1
Enter the key & value : <1,30>
****Menu****
1.Insert
2.Display
3.Delete
4.Length
Enter your choice : 2
<1,30> <2.34>
****Menu****
1.Insert
2.Display
3.Delete
4.Length
Enter your choice : 3
<2,34>

15. AIM: To find the maximum profit from the items in the bag using knap
sack problem.

ALGORITHM:
Step 1: Initialize the variables, profit, weight, p/w and maxprofit.
Step 2: Get the number of elements.
Step 3: Get the capacity of the bag.
Step 4: Get the profit of items in the bag.
Step 5: Get the weight of each item in the bag.
Step 7: Assign pw[j] to t1, p[j] to t2 and w[j] to t3.
Step 8: If w[i] > capacity then find the ratio of capacity to weight of each item.
Step 9: Else subtract the weight of the item from the total capacity.
92

Step 10: Solution vector is found and printed.


Step 11: The maximum profit is found and printed.

# include<stdio.h>
# include<conio.h>
#include<iostream.h>

void knapsack(int n, float weight[], float profit[], float capacity)


{
float x[20], tp= 0;
int i, j, u;
u=capacity;

for (i=0;i<n;i++)
x[i]=0.0;

for (i=0;i<n;i++)
{
if(weight[i]>u)
break;
else
{
x[i]=1.0;
tp= tp+profit[i];
u=u-weight[i];
}
}

if(i<n)
x[i]=u/weight[i];

tp= tp + (x[i]*profit[i]);

cout<<"n The result vector is:- ";


for(i=0;i<n;i++)
cout<<x[i];

cout<<"m Maximum profit is:- "<<tp;

void main()
{
float weight[20], profit[20], capacity;
int n, i ,j;
float ratio[20], temp;
clrscr();

cout<<"n Enter the no. of objects:- ";


cin>>num;

cout<<"n Enter the wts and profits of each object:- ";


for (i=0; i<n; i++)
{
cin>>weight[i]<<profit[i];
}

cout<<"n enter the capacityacity of knapsack:- ";


cin>>capacity;
93

for (i=0; i<n; i++)


{
ratio[i]=profit[i]/weight[i];
}

for(i=0; i<n; i++)


{
for(j=i+1;j< n; j++)
{
if(ratio[i]<ratio[j])
{
temp= ratio[j];
ratio[j]= ratio[i];
ratio[i]= temp;

temp= weight[j];
weight[j]= weight[i];
weight[i]= temp;

temp= profit[j];
profit[j]= profit[i];
profit[i]= temp;
}
}
}

knapsack(n, weight, profit, capacity);


getch();
}

Output :
Enter the no. of objects:- 7

Enter the wts and profits of each object:-


2 10
35
5 15
77
16
4 18
13

Enter the capacity of knapsack:- 15

The result vector is:- 1.000000 1.000000 1.000000 1.000000


1.000000 0.666667 0.000000

Maximum profit is:- 55.333332


94

16.AIM: To write a C++ program to implement Prims algorithm to generate a


minimum spanning tree.

Algorithm :

Given a connected graph G=(V,E) and a weight d:E->R+, find a minimum spanning
tree.

Prim's algorithm is known to be a good algorithm to find a minimum spanning tree.

1. Set i=0, S0= {u0=s}, L(u0)=0, and L(v)=infinity for v <> u0. If |V| = 1 then
stop, otherwise go to step 2.
2. For each v in V\Si, replace L(v) by min{L(v), dvui}. If L(v) is replaced, put a
label (L(v), ui) on v.
3. Find a vertex v which minimizes {L(v): v in V\Si}, say ui+1.
4. Let Si+1 = Si cup {ui+1}.
5. Replace i by i+1. If i=|V|-1 then stop, otherwise go to step 2.

The time required by Prim's algorithm is O(|V|2). It will be reduced to O(|E|log|V|) if


heap is used to keep {v in V\Si : L(v) < infinity}

Implementation:

#include<iostream.h>

class prims
{
private:
int n; //no of nodes
int graph_edge[250][4]; //edges in the graph
int g; //no of edges in the graph
int tree_edge[250][4]; //edges in the tree
int t; //no of edges in the tree
int s; //source node

//Partition the graph in to two sets


int T1[50],t1; // Set 1
int T2[50],t2; // Set 2

public:
void input();
int findset(int);
void algorithm();
void output();
};
95

void prims::input()
{
cout<<*************************************************\n
<<This program implements the prims algorithm\n
<<*************************************************\n;
cout<<Enter the no. of nodes in the undirected weighted graph ::;
cin>>n;

g=0;

cout<<Enter the weights for the following edges ::\n;


for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
cout<< < <<i<< , <<j<< > ::;
int w;
cin>>w;
if(w!=0)
{
g++;

graph_edge[g][1]=i;
graph_edge[g][2]=j;
graph_edge[g][3]=w;
}
}
}

// print the graph edges

cout<<\n\nThe edges in the given graph are::\n;


for(i=1;i<=g;i++)
cout<< < <<graph_edge[i][1]<< , <<graph_edge[i][2]<<
>::<<graph_edge[i][3]<<endl;
}

int prims::findset(int x)
{
for(int i=1;i<=t1;i++)
if(x==T1[i])
return 1;

for(i=1;i<=t2;i++)
if(x==T2[i])
return 2;
return -1;
}

void prims::algorithm()
{
t=0;
96

t1=1;
T1[1]=1; //The source node

t2=n-1;
int i;
for(i=1;i<=n-1;i++)
T2[i]=i+1; //The reamining nodes

cout<<\n*****The algorithm starts*****\n\n;

while(g!=0 && t!=n-1)


{
// Find the least cost edge
int min=9999;
int p;
int u,v,w;
for(i=1;i<=g;i++)
{
bool flag1=false,flag2=false;

//if u and v are in different sets


if(findset(graph_edge[i][1])!=findset(graph_edge[i][2]))
{
if(min>graph_edge[i][3])
{
min=graph_edge[i][3];
u=graph_edge[i][1];
v=graph_edge[i][2];
w=graph_edge[i][3];

p=i;
}
}
}

//break if there is no such edge

cout<<The edge included in the tree is ::;


cout<< < <<u<< , <<v<< > <<endl;

//delete the edge from graph edges

for(int l=p;l<g;l++)
{
graph_edge[l][1]=graph_edge[l+1][1];
graph_edge[l][2]=graph_edge[l+1][2];
graph_edge[l][3]=graph_edge[l+1][3];
}
g;

//add the edge to the tree


97

t++;
tree_edge[t][1]=u;
tree_edge[t][2]=v;
tree_edge[t][3]=w;

//Alter the set partitions


t1++;

int m;
if(findset(v)==2)
{
T1[t1]=v;
m=v;
}
else if(findset(u)==2)
{
T1[t1]=u;
m=u;
}

int x;
for(x=1;T2[x]!=m;x++);

for(;x<t2;x++)
T2[x]=T2[x+1];
t2;

// Print the sets

int k;
cout<<NOW\nT1 :: ;
for(k=1;k<=t1;k++)
cout<<T1[k]<< ;
cout<<endl;

cout<<T2 :: ;
for(k=1;k<=t2;k++)
cout<<T2[k]<< ;
cout<<endl;

cout<<The graph edges are ::\n;


for(i=1;i<=g;i++)
cout<< < <<graph_edge[i][1]
<< , <<graph_edge[i][2]
<< > ::<<graph_edge[i][3]<<endl;

cout<<endl<<endl;}}

void prims::output()
{
cout<<\nThe selected edges are ::\n;
for(int i=1;i<=t;i++)
98

cout<< < <<tree_edge[i][1]


<< , <<tree_edge[i][2]
<< > ::<<tree_edge[i][3]<<endl;
}
int main(){
prims obj;
obj.input();
obj.algorithm();obj.output();return 0;
}

You might also like