DSTCpp Lab Manual 2019
DSTCpp Lab Manual 2019
Department of
COMPUTER SCIENCE AND ENGINEERING
2018-2019
Data Structures through C++ Lab
List of Experiments
NOTE:
☀ In a single linked list, the address of the first node is always stored in
a reference node known as "front" (Some times it is also known as
"head").
☀ Always next part (reference part) of the last node must be NULL.
Example
Program :
/* Class Declaration*/
class single_list
{
public:
node *create_node(int);
void insert_begin( );
void insert_pos( );
void insert_last( );
void delete_pos( );
void display( );
single_list( )
{
start = NULL;
}
};
/* Creating Node */
node *single_list::create_node(int value)
{
struct node *temp, *s;
temp = new(struct node);
if (temp == NULL)
{
cout<<"Memory not allocated "<<endl;
return 0;
}
else
{
temp->info = value;
temp->next = NULL;
return temp;
}
}
In double linked list, every node has link to its previous node and next
node. So, we can traverse forward by using next field and can traverse
backward by using previous field. Every node in a double linked list
contains three fields and they are shown in the following figure...
Here, 'link1' field is used to store the address of the previous node in the
sequence, 'link2' field is used to store the address of the next node in the
sequence and 'data' field is used to store the actual value of that node.
Example
NOTE
☀ In double linked list, the first node must be always pointed by head.
☀ Always the previous field of the first node must be NULL.
☀ Always the next field of the last node must be NULL.
Program :
// Node Declaration
struct node
{
int info;
struct node *next;
struct node *prev;
}*start;
// Class Declaration
class double_llist
{
public:
void create_list(int value);
void add_begin(int value);
void add_after(int value, int position);
void delete_element(int value);
void search_element(int value);
void display_dlist();
void count();
void reverse();
double_llist()
{
start = NULL;
}
};
while (q != NULL)
{
cout<<q->info<<" <-> ";
q = q->next;
}
cout<<"NULL"<<endl;
}
Stack: A stack is a Last In First Out (LIFO) data structure in which all
insertions and deletions are takes place at one end, called the top. Stack
maintains a variable called top, which keeps track of the top most elements in
the stack. Any insertions or deletions should be based upon the value of top.
In the stack, the elements are removed in the reverse order of that in which
they were added to the stack that is last element inserted is to be deleted
first.
Basic Stack Operations:
push/insert : To insert an item into stack
pop/delete : To delete an item from
stack traverse/display : To display an items
isFull : To know whether the stack is full or not
isEmpty : To know whether the stack is empty or not
Program:
// C++ program to implement basic stack operations using Linked List
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct Node
{
int data;
Node *next;
} *top=NULL,*p;
Node *newNode(int x)
{
p=new Node;
p->data=x;
p->next=NULL;
return(p);
}
void push(Node *q)
{
if(top==NULL)
top=q;
else
{
q->next=top;
top=q;
}
}
void pop( )
{
if(top==NULL)
{
cout<<"Stack is empty!!";
}
else
{
cout<<"Deleted element is : "<<top->data;
p=top;
top=top->next;
delete(p);
}
}
void display( )
{
Node *q;
q=top;
if(top==NULL)
{
cout<<"Stack is empty!!";
}
else
{
while(q!=NULL)
{
cout<<q->data<<"
"; q=q->next;
}
}
}
int main()
{
int ch, x;
Node *nptr;
while(1)
{
cout<<”\n STACK OPERATIONS “<<endl;
cout<<”\n --------------------------------“<<endl;
cout<<"\n 1.Push \n 2.Pop \n 3.Display \n 4.Exit";
cout<<"\n\n Enter your choice(1-4) : ";
cin>>ch;
switch(ch)
{
case 1: cout<<"\n Enter Data Elements :"<<endl;
cin>>x;
nptr=newNode(x);
push(nptr);
break;
case 2: pop( );
break;
case 3: display( );
break;
case 4: exit(0);
default: cout<<"\nWrong choice!!";
}
}
return 0;
}
Program 4) Implement Circular Queue using Linked list
Step 1: Include all the header files which are used in the program
and define a constant 'SIZE' with specific value.
Step 2: Declare all user defined functions used in circular queue
implementation.
Step 3: Create a one dimensional array with above defined SIZE (int
cQueue[SIZE])
Step 4: Define two integer variables 'front' and 'rear' and initialize
both with '-1'. (int front = -1, rear = -1)
Step 5: Implement main method by displaying menu of operations
list and make suitable function calls to perform operation selected by
the user on circular queue.
Program:
// C++ Program to Implement Circular Linked List
#include<iostream>
#include<stdlib.h>
using namespace std;
// Node Declaration
struct node
{
int info;
struct node *next;
} *last;
// Class Declaration
class circular_llist
{
public:
void create_node(int value);
void add_begin(int value);
void add_after(int value, int position);
void delete_element(int value);
void search_element(int value);
void display_list( );
void update( );
void sort( );
circular_llist( )
{
last = NULL;
}
};
case 3:
cout<<"Enter the element : ";
cin>>element;
cout<<"Insert element after position : ";
cin>>position;
cl.add_after(element, position);
cout<<endl;
break;
case 4:
if (last == NULL)
{
cout<<"List is empty, nothing to delete "<<endl;
break;
}
cout<<"Enter the element for deletion : ";
cin>>element;
cl.delete_element(element);
cout<<endl;
break;
case 5:
if (last == NULL)
{
cout<<"List Empty!! Can't search"<<endl;
break;
}
cout<<"Enter the element to be searched : ";
cin>>element;
cl.search_element(element);
cout<<endl;
break;
case 6:
cl.display_list();
break;
case 7:
cl.update();
break;
case 8:
cl.sort();
break;
case 9:
exit(1);
break;
default:
cout<<"Wrong choice"<<endl;
}
}
return 0;
}
For Example: The following tree is a Binary Search Tree. In this tree, left
sub-tree of every node contains nodes with smaller values and right sub-tree
of every node contains larger values.
Program:
// C++ program to implement binary search tree
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct node
{
int key;
struct node *left, *right;
};
return 0;
}
Program 6 : Implementation of Hash table.
Hashing is when you take any type of data, and assign an integer value to
it. Basically you end up storing it in an array of some sort that can be
accessed based on that "key", which is the integer. A hash function is
something that takes the data as a parameter, and returns the integer value
that is the key.
Program:
// Program to implement Hash Table
#include<iostream.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<conio.h>
//using namespace std;
// Hash Function
int HashFunc(int key)
{
return key % TABLE_SIZE;
}
// Main Menu
int main()
{
HashMap hash;
int key, value;
int choice;
clrscr();
while (1)
{
cout<<"\n----------------------"<<endl;
cout<<"Operations on Hash Table"<<endl;
cout<<"----------------------"<<endl;
cout<<"1.Insert element into the table"<<endl<<endl;
cout<<"2.Search element from the key"<<endl<<endl;
cout<<"3.Delete element at a key"<<endl<<endl;
cout<<"4.Exit"<<endl<<endl;
cout<<"Enter your choice: ";
cin>>choice;
switch(choice)
{
case 1:
cout<<"Enter element to be inserted : ";
cin>>value;
cout<<"Enter key at which element to be inserted : ";
cin>>key;
hash.Insert(key, value);
break;
case 2:
cout<<"Enter key of the element to be searched : ";
cin>>key;
if(hash.Search(key) == -1)
{
cout<<"No element found at key : "<<key<<endl;
continue;
}
else
{
cout<<"Element at key :"<<key<<" : ";
cout<<hash.Search(key)<<endl;
}
break;
case 3:
cout<<"Enter key of the element to be deleted : ";
cin>>key;
hash.Remove(key);
break;
case 4:
exit(1);
default:
cout<<"\nEnter correct option\n";
}
}
return 0;
}
Program 7: Implementation of Heaps.
Heap: Heap is a special case of balanced binary tree data structure where
the root-node key is compared with its children and arranged accordingly.
If α has child node β then − key(α) ≥ key(β)
As the value of parent is greater than that of child, this property generates
Max Heap. Based on this criteria, a heap can be of two types −
For Input → 35 33 42 10 14 19 27 44 26 31
Min-Heap − Where the value of the root node is less than or equal to
either of its children.
Max-Heap − Where the value of the root node is greater than or equal to either
of its children.
Both trees are constructed using the same input and order of arrival.
Program:
// Driver program
int main()
{
int n, i, x;
cout<<"enter no of elements of array\n";
cin>>n;
int a[20];
for (i = 1; i <= n; i++)
{
cout<<"enter element"<<(i)<<endl;
cin>>a[i];
}
build_maxheap(a,n);
cout<<"Max Heap \n";
for (i = 1; i <= n; i++)
{
cout<<a[i]<<endl;
}
build_minheap(a,n);
cout<<"Min Heap \n";
for (i = 1; i <= n; i++)
{
cout<<a[i]<<endl;
}
getch();
}
Prog 8: To Implement Breadth First Search (BFS) Techniques.
BFS (Breadth First Search): BFS traversal of a graph, produces a
spanning tree as final result. Spanning Tree is a graph without any loops.
We use Queue data structure with maximum size of total number of
vertices in the graph to implement BFS traversal of a graph.
Program:
// C++ program to implementation of Breadth First Search (BFS) for a given graph
#include<iostream>
#include<conio.h>
#include<stdlib.h>
void main( )
{
cout<<"\n Enter no of vertices : ";
cin>>nv;
cout<<"\n Ente no of edges : ";
cin>>ne;
cout<<"\n Enter EDGES one by one : \n";
for(k=1; k<=ne; k++)
{
cin>>i>>j;
cost[i][j]=1;
}
cout<<"\n Enter Initial(starting) Vertex : ";
cin>>sv;
cout<<"\n Final Result of BFS Traversal is :
"; cout<<sv<<" ";
visited[sv]=1;
k=1;
while(k<nv)
{
for(j=1; j<=nv; j++)
if(cost[sv][j]!=0 && visited[j]!=1 && visit[j]!=1)
{
visit[j]=1;
que[rare++]=j;
}
sv=que[front++];
cout<<sv<<" ";
k++;
visit[sv]=0;
visited[sv]=1;
}
}
Prog 9: To Implement Depth First Search (DFS) Techniques.
DFS (Depth First Search): DFS traversal of a graph, produces a spanning
tree as final result. Spanning Tree is a graph without any loops. We use
Stack data structure with maximum size of total number of vertices in the
graph to implement DFS traversal of a graph.
We use the following steps to implement DFS traversal:
Step 1: Define a Stack of size total number of vertices in the graph.
Step 2: Select any vertex as starting point for traversal. Visit that vertex
and push it on to the Stack.
Step 3: Visit any one of the adjacent vertex of the vertex which is at top of
the stack which is not visited and push it on to the stack.
Step 4: Repeat step 3 until there are no new vertex to be visit from the
vertex on top of the stack.
Step 5: When there is no new vertex to be visit then use back tracking and
pop one vertex from the stack.
Step 6: Repeat steps 3, 4 and 5 until stack becomes Empty.
Step 7: When stack becomes Empty, then produce final spanning tree by
removing unused edges from the graph
Note : Back tracking is coming back to the vertex from which we came to
current vertex.
Program:
// C++ program for the implementation of Depth-first search (DFS) for a given
graph
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
int cost[10][10], stk[10], visit[10], visited[10], nv, ne, sv, top, i, j,
k;
void main( )
{
cout<<"\n Enter no of vertices : ";
cin>>nv;
cout<<"\n Ente no of edges : ";
cin>>ne;
cout<<"\n Enter EDGES one by one : \n";
for(k=1; k<=ne; k++)
{
cin>>i>>j;
cost[i][j]=1;
}
cout<<"\n Enter initial(Starting) vertex : ";
cin>>sv;
cout<<"\n The Result of DFS Traversal is : ";
cout<<sv<<" ";
visited[sv]=1;
k=1;
while(k<nv)
{
for(j=nv; j>=1; j--)
if(cost[sv][j]!=0 && visited[j]!=1 && visit[j]!=1)
{
visit[j]=1;
stk[top]=j;
top++;
}
sv=stk[--top];
cout<<sv<<" ";
k++;
visit[sv]=0;
visited[sv]=1;
}
}
Program 10: Implementation of Prim’s Algorithm
Dijkstra's algorithm allows us to find the shortest path between any two
vertices of a graph. Dijkstra’s algorithm is very similar to Prim’s algorithm
for minimum spanning tree. Like Prim’s MST, we generate a SPT
(shortest path tree) with given source as root. We maintain two sets, one
set contains vertices included in shortest path tree, other set includes
vertices not yet included in shortest path tree. At every step of the
algorithm, we find a vertex which is in the other set (set of not yet
included) and has a minimum distance from the source.
Algorithm
1) Create a set sptSet (shortest path tree set) that keeps track of vertices
included in shortest path tree, i.e., whose minimum distance from source is
calculated and finalized. Initially, this set is empty.
2) Assign a distance value to all vertices in the input graph. Initialize all
distance values as INFINITE. Assign distance value as 0 for the source
vertex so that it is picked first.
a) Pick a vertex u which is not there in sptSet and has minimum distance
value.
b) Include u to sptSet.
It is easier to start with an example and then think about the algorithm.
Program:
// Implementation of Dijkstra's Algorithm
#include<iostream>
#include<conio.h>
#include<stdio.h>
//using namespace std;
for(j=1;j<=n;j++)
{
if(dist[j]<min && s[j]!=1)
{
min=dist[j];
k=j;
}
}
if(cost[v][k]<=dist[k])
p=1;
path[++p]=k;
for(j=1;j<=p;j++)
cout<<path[j]<<" ";
cout<<"\n";
s[k]=1;
for(j=1;j<=n;j++)
if(cost[k][j]!=31999 && dist[j]>=dist[k]+cost[k][j] && s[j]!=1)
dist[j]=dist[k]+cost[k][j];
}
return 0;
}
Program 12: Implementation of Kruskal’s Algorithm
Merge Sort: Merge Sort is a Divide and Conquer algorithm. It divides input
array in two halves, calls itself for the two halves and then merges the two
sorted halves. The merge() function is used for merging two halves.
The merge(arr, l, m, r) is key process that assumes that arr[l..m] and arr[m+1..r]
are sorted and merges the two sorted sub-arrays into one.
If (r > l)
1. Find the middle point to divide the array into two halves:
middle m = (l+r) / 2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, l, m, r)
Program:
int main( )
{
int arr[25], n, i;
cout<<"\nEnter the number of data element to be sorted : ";
cin>>n;
cout<<endl;
for(i=0; i<n; i++)
{
cout<<"Enter "<<i+1<<" data element :";
cin>>arr[i];
}
// Before Soring the Actulal order of the data elements
cout<<"\nActual Data Elements:";
for(i=0; i<n; i++)
cout<<"-> "<<arr[i];
MergeSort(arr, 0, n-1);
// Printing the sorted data.
cout<<"\n\nSorted Data Elements:";
for(i=0; i<n; i++)
cout<<"-> "<<arr[i];
return 0;
}
Prog 14: Implementation of Quick Sort
Quick Sort: Quick sort is based on the divide-and-conquer approach based on
the idea of choosing one element as a pivot element and partitioning the array
around it such that: Left side of pivot contains all the elements that are less than
the pivot element Right side contains all elements greater than the pivot.
if(l<h)
{
t=a[l];
a[l]=a[h];
a[h]=t;
}
else
{
t=pvt;
pvt=a[l];
a[l]=t;
break;
}
}
return h;
}
void quick(int l, int h, int *a)
{
int index, i;
if(l<h)
{
index=part(l, h, a);
quick(l, index-1, a);
quick(index+1, h, a);
}
}
int main( )
{
int arr[100],n,i,l,h;
cout<<"\nEnter the number of data element to be sorted : ";
cin>>n;
cout<<endl;
Binary search looks for a particular item by comparing the middle most
item of the collection. If a match occurs, then the index of item is returned.
If the middle item is greater than the item, then the item is searched in the
sub-array to the left of the middle item. Otherwise, the item is searched for
in the sub-array to the right of the middle item. This process continues on
the sub-array as well until the size of the sub array reduces to zero.
Step 1 : low = 0;
Step 2 : high = size - 1;
Step 3 : while (low <= high)
{ /* Calculate mid index */
mid = (low + high) / 2;
Step 4 : /*If element is found at mid index then return the index */
if (arr[mid] == num )
{
return mid+1;
}
else if ( arr[mid] > num)
{
high = mid - 1;
}
else if ( arr[mid] < num)
{
low = mid + 1;
}
Step 5: /* If element is not found return -1 */
return -1;
}
Program:
Write a C++ program that implements Data Searching using Divide
and Conquer ( Binary Search) technique.
// Data Element Search Using Divide and Conquer method (Binary Search)
#include <iostream>
#include<stdlib.h>
#define SIZE 5
void main( )
{
int list[SIZE], target, index, i;
char ch;
cout<<"Enter " <<SIZE <<" elements in ascending or descending order :"<<endl;
for(i=0; i<SIZE; i++)
cin>>list[i];
do
{
cout<<"\n Enter an element that is to be searched : ";
cin>>target;
index = binary_search(list, 0, SIZE-1, target);
if(index != -1)
cout<<"\n\n Target element was found at position : "<<index+1;
else
cout<<"\n\n Sorry, target item was not found";
cout<<"\n\n Do you want to continue...(y/n) : ";
cin>>ch;
}
while(ch!='n');
}