1-1 MTech ADSA Manual
1-1 MTech ADSA Manual
2. Multiplication Method
h(k) = ⌊m(kA mod 1)⌋
where,
kA mod 1 gives the fractional part kA,
⌊ ⌋ gives the floor value
A is any constant. The value of A lies between 0 and 1. But, an optimal choice will
be ≈ (√5-1)/2 suggested by Knuth.
3. Universal Hashing
In Universal hashing, the hash function is chosen at random independent of keys.
Source Code:
#include <iostream>
#include <list>
using namespace std;
class HashTable
{
int capacity;
list<int> *table;
public:
HashTable(int V);
void insertItem(int key, int data);
void deleteItem(int key);
int checkPrime(int n)
{
int i;
if (n == 1 || n == 0)
{
return 0;
}
for (i = 2; i < n / 2; i++)
{
if (n % i == 0)
{
return 0;
}
}
return 1;
}
int getPrime(int n)
{
if (n % 2 == 0)
{
n++;
}
while (!checkPrime(n))
{
n += 2;
}
return n;
}
list<int>::iterator i;
for (i = table[index].begin();
i != table[index].end(); i++)
{
if (*i == key)
break;
}
if (i != table[index].end())
table[index].erase(i);
}
void HashTable::displayHash()
{
for (int i = 0; i < capacity; i++)
{
cout << "table[" << i << "]";
for (auto x : table[i])
cout << " --> " << x;
cout << endl;
}
}
int main()
{
int key[] = {231, 321, 212, 321, 433, 262};
int data[] = {123, 432, 523, 43, 423, 111};
int size = sizeof(key) / sizeof(key[0]);
HashTable h(size);
h.deleteItem(12);
h.displayHash();
}
Output:
table[0] --> 123
table[1]
table[2] --> 523
table[3] --> 111
table[4]
table[5]
table[6] --> 432 --> 43 --> 423
2. Operations on AVL Trees
Aim: To implement various operations on AVL trees.
Description:
An AVL tree defined as a self-balancing Binary Search Tree (BST) where the
difference between heights of left and right subtrees for any node cannot be more
than one.
Example:
#include <iostream>
using namespace std;
struct Node {
int key1;
int key2;
Node* child1;
Node* child2;
Node* child3;
bool isTwoNode;
Node(int k1, Node* c1 = nullptr, Node* c2 = nullptr, bool isTwo = true)
: key1(k1), key2(-1), child1(c1), child2(c2), child3(nullptr), isTwoNode(isTwo)
{}
Node(int k1, int k2, Node* c1 = nullptr, Node* c2 = nullptr, Node* c3 = nullptr)
: key1(k1), key2(k2), child1(c1), child2(c2), child3(c3), isTwoNode(false) {}
};
class TwoThreeTree {
private:
Node* root;
// Helper functions
Node* insert(Node* root, int key);
Node* split(Node* root);
Node* merge(Node* root);
Node* findMin(Node* root);
Node* remove(Node* root, int key);
void display(Node* root, int level);
public:
TwoThreeTree() : root(nullptr) {}
if (root->isTwoNode) {
if (key < root->key1) {
root->key2 = root->key1;
root->key1 = key;
} else if (key > root->key1) {
root->key2 = key;
}
} else {
if (key < root->key1) {
root->child1 = insert(root->child1, key);
} else if (key > root->key2) {
root->child3 = insert(root->child3, key);
} else {
root->child2 = insert(root->child2, key);
}
}
if (root->key2 != -1) {
return split(root);
}
return root;
}
if (root == this->root) {
this->root = new Node(root->key1, root, newNode, true);
return this->root;
} else {
return newNode;
}
}
void TwoThreeTree::display() {
display(root, 0);
}
int main() {
TwoThreeTree tree;
int x,y,c;
char ch;
do
{
cout<<"\n1.Insert";
cout<<"\n2.Display";
cout<<"\n3.Delete";
cout<<"\n4.Search";
cout<<"\n5.Exit";
cout<<"\nEnter your choice of operation on 2-3 Tree :";
cin>>c;
switch(c)
{
case 1:
cout<<"\nEnter an Element to be inserted into Tree :";
cin>>x;
tree.insert(x);
break;
case 2:
tree.display();
break;
case 3:
cout<<"\nEnter an item for Deletion :";
cin>>y;
tree.remove(y);
break;
case 4:
cout<<"\nEnter an element to perform Search :";
cin>>c;
cout << (tree.search(c) ? "Element Found" : "Element Not Found");
break;
case 5:
exit(0);
break;
default :
cout<<"\nInvalid option try again";
}
cout<<"\nDo u want to continue (y/n) :";
cin>>ch;
}
while(ch=='y'||ch=='Y');
return 0;
}
Output:
1.Insert
2.Display
3.Delete
4.Search
5.Exit
Enter your choice of operation on 2-3 Tree :1
Enter an Element to be inserted into Tree :8
Do u want to continue (y/n) :y
1.Insert
2.Display
3.Delete
4.Search
5.Exit
Enter your choice of operation on 2-3 Tree :1
Enter an Element to be inserted into Tree :11
Do u want to continue (y/n) :y
1.Insert
2.Display
3.Delete
4.Search
5.Exit
Enter your choice of operation on 2-3 Tree :1
Enter an Element to be inserted into Tree :7
Do u want to continue (y/n) :y
1.Insert
2.Display
3.Delete
4.Search
5.Exit
Enter your choice of operation on 2-3 Tree :2
7
7
8
8,-1
11,-1
Source code:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <iterator>
using namespace std;
class BHeap {
private:
vector <int> heap;
int l(int parent);
int r(int parent);
int par(int child);
void heapifyup(int index);
void heapifydown(int index);
public:
BHeap() {}
void Insert(int element);
void DeleteMin();
int ExtractMin();
void showHeap();
int Size();
};
int main() {
BHeap h;
while (1) {
cout<<"1.Insert Element"<<endl;
cout<<"2.Delete Minimum Element"<<endl;
cout<<"3.Extract Minimum Element"<<endl;
cout<<"4.Show Heap"<<endl;
cout<<"5.Exit"<<endl;
int c, e;
cout<<"Enter your choice: ";
cin>>c;
switch(c) {
case 1:
cout<<"Enter the element to be inserted: ";
cin>>e;
h.Insert(e);
break;
case 2:
h.DeleteMin();
break;
case 3:
if (h.ExtractMin() == -1) {
cout<<"Heap is Empty"<<endl;
}
else
cout<<"Minimum Element: "<<h.ExtractMin()<<endl;
break;
case 4:
cout<<"Displaying elements of Hwap: ";
h.showHeap();
break;
case 5:
exit(1);
default:
cout<<"Enter Correct Choice"<<endl;
}
}
return 0;
}
int BHeap::Size() {
return heap.size();
}
void BHeap::Insert(int ele) {
heap.push_back(ele);
heapifyup(heap.size() -1);
}
void BHeap::DeleteMin() {
if (heap.size() == 0) {
cout<<"Heap is Empty"<<endl;
return;
}
heap[0] = heap.at(heap.size() - 1);
heap.pop_back();
heapifydown(0);
cout<<"Element Deleted"<<endl;
}
int BHeap::ExtractMin() {
if (heap.size() == 0) {
return -1;
}
else
return heap.front();
}
void BHeap::showHeap() {
vector <int>::iterator pos = heap.begin();
cout<<"Heap --> ";
while (pos != heap.end()) {
cout<<*pos<<" ";
pos++;
}
cout<<endl;
}
int BHeap::l(int parent) {
int l = 2 * parent + 1;
if (l < heap.size())
return l;
else
return -1;
}
int BHeap::r(int parent) {
int r = 2 * parent + 2;
if (r < heap.size())
return r;
else
return -1;
}
int BHeap::par(int child) {
int p = (child - 1)/2;
if (child == 0)
return -1;
else
return p;
}
void BHeap::heapifyup(int in) {
if (in >= 0 && par(in) >= 0 && heap[par(in)] > heap[in]) {
int temp = heap[in];
heap[in] = heap[par(in)];
heap[par(in)] = temp;
heapifyup(par(in));
}
}
void BHeap::heapifydown(int in) {
int child = l(in);
int child1 = r(in);
if (child >= 0 && child1 >= 0 && heap[child] > heap[child1]) {
child = child1;
}
if (child > 0 && heap[in] > heap[child]) {
int t = heap[in];
heap[in] = heap[child];
heap[child] = t;
heapifydown(child);
}
}
Output
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 1
Enter the element to be inserted: 2
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 1
Enter the element to be inserted: 3
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 1
Enter the element to be inserted: 7
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 1
Enter the element to be inserted: 6
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 4
Displaying elements of Hwap: Heap --> 2 3 7 6
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 3
Minimum Element: 2
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 3
Minimum Element: 2
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 2
Element Deleted
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 4
Displaying elements of Hwap: Heap --> 3 6 7
1.Insert Element
2.Delete Minimum Element
3.Extract Minimum Element
4.Show Heap
5.Exit
Enter your choice: 5
5. Operations on Graphs
Aim: To implement operations on graphs.
Description:
Graph is a non-linear data structure consisting of a set of vertices( V ) and a set of
edges( E ).
The graph is denoted by G(V, E).
class Graph {
private:
int vertices;
list<int> *adjList;
public:
Graph(int V) {
vertices = V;
adjList = new list<int>[V];
}
void traverseGraph() {
for (int i = 0; i < vertices; ++i) {
cout << "Vertex " << i << " -> ";
for (const auto &neighbor : adjList[i]) {
cout << neighbor << " ";
}
cout << endl;
}
}
int main() {
int vertices, choice, v, w;
do {
cout << "\nMenu:\n1. Insert Edge\n2. Delete Edge\n3. Traverse Graph\n4.
Search Edge\n0. Exit\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "Enter the vertices for the edge (space-separated): ";
cin >> v >> w;
graph.addEdge(v, w);
cout << "Edge (" << v << ", " << w << ") inserted.\n";
break;
case 2:
cout << "Enter the vertices for the edge to delete (space-separated): ";
cin >> v >> w;
graph.deleteEdge(v, w);
cout << "Edge (" << v << ", " << w << ") deleted.\n";
break;
case 3:
cout << "Graph Traversal:\n";
graph.traverseGraph();
break;
case 4:
cout << "Enter the vertices for the edge to search (space-separated): ";
cin >> v >> w;
if (graph.searchEdge(v, w))
cout << "Edge (" << v << ", " << w << ") found.\n";
else
cout << "Edge (" << v << ", " << w << ") not found.\n";
break;
case 0:
cout << "Exiting the program.\n";
break;
default:
cout << "Invalid choice. Please try again.\n";
}
return 0;
}
Output:
Enter the number of vertices in the graph: 4
Menu:
1. Insert Edge
2. Delete Edge
3. Traverse Graph
4. Search Edge
0. Exit
Enter your choice: 1
Enter the vertices for the edge (space-separated): 0 1
Edge (0, 1) inserted.
Menu:
1. Insert Edge
2. Delete Edge
3. Traverse Graph
4. Search Edge
0. Exit
Enter your choice: 1
Enter the vertices for the edge (space-separated): 1 2
Edge (1, 2) inserted.
Menu:
1. Insert Edge
2. Delete Edge
3. Traverse Graph
4. Search Edge
0. Exit
Enter your choice: 3
Graph Traversal:
Vertex 0 -> 1
Vertex 1 -> 0 2
Vertex 2 -> 1
Vertex 3 ->
Menu:
1. Insert Edge
2. Delete Edge
3. Traverse Graph
4. Search Edge
0. Exit
Enter your choice: 2
Enter the vertices for the edge to delete (space-separated): 1 2
Edge (1, 2) deleted.
Menu:
1. Insert Edge
2. Delete Edge
3. Traverse Graph
4. Search Edge
0. Exit
Enter your choice: 3
Graph Traversal:
Vertex 0 -> 1
Vertex 1 -> 0
Vertex 2 ->
Vertex 3 ->
Menu:
1. Insert Edge
2. Delete Edge
3. Traverse Graph
4. Search Edge
0. Exit
Enter your choice: 0
Exiting the program.
6. Depth First Search
Aim: To implement Depth First Search for a graph non-recursively.
Description:
Depth-First Search (DFS) is a graph traversal algorithm exploring as far as possible
along each branch before backtracking. It systematically visits vertices, marking
them as visited. DFS is efficient for connectivity analysis and topological sorting.
Source code:
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
// Graph Constructor
Graph(vector<Edge> const &edges, int n)
{
// resize the vector to hold `n` elements of type `vector<int>`
adjList.resize(n);
// we will reach here if the popped vertex `v` is not discovered yet;
// print `v` and process its undiscovered adjacent nodes into the stack
discovered[v] = true;
cout << v << " ";
int main()
{
// vector of graph edges as per the above diagram
vector<Edge> edges = {
// Notice that node 0 is unconnected
{1, 2}, {1, 7}, {1, 8}, {2, 3}, {2, 6}, {3, 4},
{3, 5}, {8, 9}, {8, 12}, {9, 10}, {9, 11}
// {6, 9} introduces a cycle
};
Output:
0 1 2 3 4 5 6 7 8 9 10 11 12
7. Breadth First Search
Aim: To implement Breadth First Search for a graph non-recursively.
Description:
Breadth-First Search (BFS) is a graph traversal algorithm exploring vertices level by
level. Starting from a source, it visits neighbors before moving deeper, ensuring
the shortest path is found. BFS is well-suited for finding the shortest path and
connected components.
Source code:
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// Graph Constructor
Graph(vector<Edge> const &edges, int n)
{
// resize the vector to hold `n` elements of type `vector<int>`
adjList.resize(n);
int main()
{
// vector of graph edges as per the above diagram
vector<Edge> edges = {
{1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {5, 9},
{5, 10}, {4, 7}, {4, 8}, {7, 11}, {7, 12}
// vertex 0, 13, and 14 are single nodes
};
return 0;
}
Output:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
8. Prim’s Algorithm
Aim: To implement Prim’s algorithm to generate a min-cost spanning tree.
Description:
Prim's algorithm is a minimum spanning tree algorithm that takes a graph as
input and finds the subset of the edges of that graph which
form a tree that includes every vertex
has the minimum sum of weights among all the trees that can be formed
from the graph
class Graph
{
// Function to allocate a new node for the adjacency list
Node* getAdjListNode(int dest, Node* head)
{
Node* newNode = new Node;
newNode->val = dest;
return newNode;
}
public:
// Constructor
Graph(Edge edges[], int n, int N)
{
// allocate memory
head = new Node*[N]();
this->N = N;
/*
newNode = getAdjListNode(src, head[dest]);
// Destructor
~Graph() {
for (int i = 0; i < N; i++) {
delete[] head[i];
}
delete[] head;
}
};
// construct graph
Graph graph(edges, n, N);
return 0;
}
Output:
0 —> 1
1 —> 2
2 —> 1 —> 0
3 —> 2
4 —> 5
5 —> 4
9. Kruskal’s Algorithm
Aim: To implement Kruskal’s Algorithm to generate a minimum-cost spanning
tree:
Description:
Kruskal's Algorithm is a widely known graph algorithm for MST detection .A
Minimum Spanning Tree is a tree that contains all vertices of graph with n-1 edges
that sum up to give minimum weight.
ALGORITHM
Step 1: Create a forest in such a way that each graph is a separate tree.
Step 2: Create a priority queue Q that contains all the edges of the graph.
Step 3: Repeat Steps 4 and 5 while Q is NOT EMPTY
Step 4: Remove an edge from Q
Step 5: IF the edge obtained in Step 4 connects two different trees, then Add it to
the forest (for combining two trees into one tree).
ELSE
Discard the edge
Step 6: END
Source Code:
#include<iostream>
#include <algorithm>
#include<vector>
using namespace std;
class edge{
public:
int s;
int d;
int w;
edge()
{
}
edge(int src,int des,int wei){
s=src;
d=des;
w=wei;
}
};
class graph{
public:
int e,n;
edge* v;
edge* unionfind(){
int* parent=new int[n];
for(int i=0;i<n;i++){
parent[i]=i;
}
sort(v,v+e,compare);
edge* output;
output=new edge[n-1];
int count=0,i=0;
while(count!=n-1){
edge c=v[i];
int sourceparent=findparent(v[i].s,parent);
int desparent=findparent(v[i].d,parent);
if(sourceparent!=desparent){
output[count]=c;
parent[sourceparent]=desparent;
count++;
}
i++;
}
int sum=0;
cout<<endl<<"-------MST-------\n";
for(int i=0;i<n-1;i++){
cout<<output[i].s<<" "<<output[i].d<<" "<<output[i].w<<endl;
sum+=output[i].w;
}
cout<<"\nWEIGHT OF MST IS "<<sum;
return output;
}
};
int main(){
int n,e;
cout<<"KRUSKAL'S ALGORITHM\nENTER NUMBER OF VERTICES : ";
cin>>n;
cout<<"ENTER NUMBER OF EDGEES : ";
cin>>e;
graph g(n,e);
edge* mst=g.unionfind();
}
OUTPUT:
KRUSKAL'S ALGORITHM
ENTER NUMBER OF VERTICES : 4
ENTER NUMBER OF EDGEES : 5
ENTER VERTICES AND WEIGHT OF EDGE 1 : 0 1 10
ENTER VERTICES AND WEIGHT OF EDGE 2 : 1 2 6
ENTER VERTICES AND WEIGHT OF EDGE 3 : 0 3 5
ENTER VERTICES AND WEIGHT OF EDGE 4 : 0 3 15
ENTER VERTICES AND WEIGHT OF EDGE 5 : 2 3 4
-------MST-------
234
035
126
WEIGHT OF MST IS 15
10. Dijkstra’s Algorithm
Aim: To implement Dijkstra’s algorithm to find shortest path in the graph
Description:
Dijkstra's algorithm is used to find the shortest paths from a single source vertex
to all other vertices in a weighted graph. The algorithm assumes that all edge
weights are non-negative. Dijkstra's algorithm uses a greedy approach, always
choosing the vertex with the minimum known distance at each step.
Source Code:
#include<iostream>
using namespace std;
int N;
int graph[10][10];
int dist[10];
bool visited[10];
int parent[10];
void createGraph()
{
int i,j,max,u,v,w;
cout<<"Enter the number of nodes : ";
cin>>N;
for(i=0;i<=N;i++)
for(j=0;j<=N;j++)
graph[i][j]=0;
max=N*(N+1);
for(i=0;i<max;i++)
{
cout<<"Enter Edge and Weight : ";
cin>>u>>v>>w;
if(u==-1) break;
else
{
graph[u][v]=w;
graph[v][u]=w;
}
}
}
int minDistance()
{
int min = 10000, minDist;
for (int v = 0; v < N; v++)
if (visited[v] == false && dist[v] <= min)
{
min = dist[v];
minDist = v;
}
return minDist;
}
void printPath(int j)
{
if (parent[j]==-1)
return;
printPath(parent[j]);
cout<<j<<" ";
}
void dijkstra()
{
int src;
cout<<"Enter the Source Node : ";
cin>>src;
for (int i = 0; i < N; i++)
{
parent[0] = -1;
dist[i] = 10000;
visited[i] = false;
}
dist[src] = 0;
for (int count = 0; count < N-1; count++)
{
int u = minDistance();
visited[u] = true;
for (int v = 0; v < N; v++)
if (!visited[v] && graph[u][v] &&
dist[u] + graph[u][v] < dist[v])
{
parent[v] = u;
dist[v] = dist[u] + graph[u][v];
}
}
cout<<"Src->Dest\tDistance\tPath"<<endl;
for (int i = 1; i < N; i++)
{
cout<<src<<"->"<<i<<"\t\t"<<dist[i]<<"\t\t"<<src<<" ";
printPath(i);
cout<<endl;
}
}
int main()
{
createGraph();
dijkstra();
return 0;
}
OUTPUT
Enter the number of nodes : 5
Enter Edge and Weight : 0 1 3
Enter Edge and Weight : 1 2 4
Enter Edge and Weight : 1 3 2
Enter Edge and Weight : 0 3 7
Enter Edge and Weight : 2 3 5
Enter Edge and Weight : 3 4 4
Enter Edge and Weight : 2 4 6
Enter Edge and Weight : -1 -1 -1
Enter the Source Node : 0