Professional Documents
Culture Documents
A)Division Method
DESCRIPTION:
If k is a key and m is the size of the hash table, the hash function h() is calculated as:
h(k) = k mod m
For example, If the size of a hash table is 10 and k = 112 then h(k) = 112 mod 10 = 2. The
value of m must not be the powers of 2. This is because the powers of 2 in binary format are
10, 100, 1000, ….
When we find k mod m, we will always get the lower order p-bits.
PROGRAM:
#include
<stdio.h
#define size 7
int arr[size];
void init() {
1;
value, key);
} else { printf("Collision: arr[%d] has element %d already!\n",
if (arr[key] == value)
arr[key] = -1;
else
(arr[key] == value)
printf("Search Found\n");
Found\n");
} void
print() {
} int
main() {
init();
print();
printf("\n");
printf("Searching value
98..\n"); search(98);
printf("Searching value
0; }
OUTPUT:
22 inserted at arr[1]
45 inserted at arr[3]
76 inserted at arr[6]
98 inserted at
arr[0] = 98 arr[1]
= 22
arr[2] = -1
arr[3] = 45
arr[4] = -1
arr[5] = -1
arr[6] = 76
arr[0] = 98 arr[1] = 22
arr[2] = -1
arr[3] = -1
arr[4] = -1
arr[5] = -1
arr[6] = 76
22
arr[2] = -1
arr[3] = -1
arr[4] = -1
arr[5] = -1
arr[6] = 76
Search Found
B) Multiplication method :
DESCRIPTION:
where,
PROGRAM:
#include<stdio.h>
#include<math.
7 int arr[size];
void init() {
1;
}
if (arr[key] == value)
value);
(arr[key] == value)
printf("Search Found\n");
Found\n");
} void
print() {
main() {
insert(32); insert(12);
65..\n"); del(65);
OUTPUT:
78 inserted at arr[1]
Unable to insert 65
32 inserted at arr[5]
12 inserted at
arr[0] = -1 arr[1]
= 78 arr[2] = 12
arr[3] = -1 arr[4]
= -1 arr[5] = 32
arr[6] = -1
Deleting value 32.. 32 not
= 12 arr[3] = -1 arr[4] = -1
arr[5] = 32
arr[6] = -1
= 12 arr[3] = -1 arr[4] = -1
arr[5] = 32 arr[6] = -1
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
struct set {
int key;
int data;
}; struct set *array; int
hashFunction(int key) {
checkPrime(int n) { if (n
== 1 || n == 0) { return
2; i++) { if (n % i == 0)
{ return 0; } }
{ if (n % 2 == 0) {
n++; } while
(!checkPrime(n)) { n +=
init_array() {
array[i].data = 0; }
hashFunction(key); if (array[index].data ==
0) { array[index].key = key;
} else { printf("\nCollision
occurred\n");
(array[index].data == 0) {
} else {
array[index].key = 0;
array[index].data = 0;
size--;
} void display() {
if (array[i].data == 0) {
i, array[i].data); } }
int c = 0; init_array();
do {
printf("\n1. Insert item in the Hash Table\n2. Remove item from the Hash Table\n3.
Check the size of Hash Table\n4. Display Hash Table\n\nPlease enter your choice: ");
scanf("%d", &key);
scanf("%d", &data);
case 2:
remove_element(key);
break;
case 3:
n = size_of_hashtable();
break;
default:
printf("Invalid Input\n"); }
return 0; }
OUTPUT:
1. Insert item in the Hash Table
Enter key: 23
3. Check the size of Hash Table 4. Display Hash Table Please enter your choice: 4
Hash
Table:
array[0]: /
array[1]: /
array[2]: /
array[3]: /
array[4]: /
array[5]: /
key: 23,
array[6]:
345
array[7]: /
array[8]: /
array[9]: /
array[10]:
array[11]:
array[12]:
array[13]:
array[14]:
array[15]:
/
array[16]:
DESCRIPTION:
Insertion in AVL trees:
In the AVL tree, the new node is always added as a leaf node. After the insertion of the new
node, it is necessary to modify the balance factor of each node in the AVL tree using the
rotation operations. The algorithm steps of insertion operation in an AVL tree are:
1. Find the appropriate empty subtree where the new value should be added by
comparing the values in the tree
2. Create a new node at the empty subtree
3. The new node is a leaf ad thus will have a balance factor of zero
4. Return to the parent node and adjust the balance factor of each node through the
rotation process and continue it until we are back at the root. Remember that the
modification of the balance factor must happen in a bottom-up fashion
The deletion operation in the AVL tree is the same as the deletion operation in BST. In the
AVL tree, the node is always deleted as a leaf node and after the deletion of the node, the
balance factor of each node is modified accordingly. Rotation operations are used to modify
the balance factor of each node. The algorithm steps of deletion operation in an AVL tree
are:
PROGRAM:
#include <stdio.h>
#include<stdlib.h>
struct node { int
data; struct node
*left; struct node
*right; int ht;
};
struct node *root = NULL;
struct node *create(int data) {
struct node *new_node = (struct node *)malloc(sizeof(struct
node)); if (new_node == NULL) { printf("\nMemory
can't be allocated\n"); return NULL;
}
new_node->data = data;
new_node->left = NULL;
new_node->right = NULL;
return new_node; }
struct node *rotate_left(struct node
*root) { struct node *right_child =
root->right; root->right = right_child-
>left; right_child->left = root; root-
>ht = height(root); right_child->ht =
height(right_child); return
right_child;
}
struct node *rotate_right(struct node
*root) { struct node *left_child = root-
>left; root->left = left_child->right;
left_child->right = root; root->ht =
height(root); left_child->ht =
height(left_child); return left_child; }
int balance_factor(struct node *root) { if
(root == NULL) return 0; int lh =
root->left ? root->left->ht + 1 : 0; int rh
= root->right ? root->right->ht + 1 : 0;
return lh - rh; } int height(struct node
*root) { if (root == NULL) return
0; int lh = root->left ? root->left->ht + 1
: 0; int rh = root->right ? root->right->ht
+ 1 : 0; return (lh > rh) ? lh : rh;
}
struct node *insert(struct node *root, int
data) { if (root == NULL) { struct
node *new_node = create(data); if
(new_node == NULL) return
NULL; root = new_node; } else if
(data > root->data) { root->right =
insert(root->right, data); if
(balance_factor(root) == -2) { if
(data > root->right->data) root =
rotate_left(root); else {
root->right = rotate_right(root->right);
root = rotate_left(root);
}
}
} else { root->left = insert(root-
>left, data); if (balance_factor(root)
== 2) { if (data < root->left-
>data) root =
rotate_right(root); else {
root->left = rotate_left(root->left);
root = rotate_right(root);
}
}
}
root->ht =
height(root); return
root; }
struct node *delete(struct node *root, int x) {
// Implementation of delete function is omitted for brevity.
}
struct node *search(struct node *root, int
key) { if (root == NULL || root->data ==
key) return root; if (key > root-
>data) return search(root->right, key);
return search(root->left, key);
} int main() { int user_choice, data; char
user_continue = 'y'; struct node *result = NULL;
while (user_continue == 'y' || user_continue == 'Y')
{ printf("\n\n------- AVL TREE --------\n");
printf("\n1. Insert"); printf("\n2. Delete");
printf("\n3. Search"); printf("\n7. EXIT");
printf("\n\nEnter Your Choice: "); scanf("%d",
&user_choice); switch (user_choice) {
case 1:
printf("\nEnter data:
"); scanf("%d", &data);
root = insert(root, data);
break; case 2:
printf("\nEnter data: ");
scanf("%d", &data); root =
delete(root, data); break;
case 3:
printf("\nEnter data: ");
scanf("%d", &data); result =
search(root, data); if (result
== NULL) printf("\nNode
not found!\n"); else
printf("\nNode found\n");
break;
case 7:
printf("\n\tProgram
Terminated\n"); return 0;
default:
printf("\n\tInvalid Choice\n");
}
printf("\nDo you want to continue? (y/n): ");
scanf(" %c", &user_continue);
}
return 0;
}
OUTPUT:
------- AVL TREE --------
1. Insert
2. Delete
3. Search
7. EXIT
Enter Your Choice: 1
Enter data: 4
Do you want to continue? (y/n): Y
------- AVL TREE --------
1. Insert
2. Delete
3. Search
7. EXIT
Enter Your Choice: 1
Enter data: 45
Do you want to continue? (y/n):
------ AVL TREE --------
1. Insert
2. Delete
3. Search
7. EXIT
Enter Your Choice: 1
Enter data: 32
Do you want to continue? (y/n): Y
------- AVL TREE --------
1. Insert
2. Delete
3. Search 7. EXIT
Enter Your Choice: 2
Enter data: 3
Do you want to continue? (y/n): Y
------- AVL TREE --------
1. Insert
2. Delete
3. Search 7. EXIT
Enter Your Choice: 3
Enter data: 32
Node found
Do you want to continue? (y/n): Y
------- AVL TREE --------
1. Insert
2. Delete
3. Search 7. EXIT
Enter Your Choice: 7
Program Terminated
EXPERIMENT NO: 03
a)Perform various operations i.e., insertions and deletions on 2-3 trees
DESCRIPTION: 2-3 trees are the data structure same as trees, but it has some different
properties like any node can have either single value or double value. So, there are two types
of nodes in 2-3 trees:
Single valued
If a node is single-valued then it has two children. Left children will contain values less than
parent value, and right children will contain values greater than parent value.
Double valued
If a node has two values then it will have three children. Left children will contain values
lesser than the left parent value, and middle children will contain values greater than the left
parent value but less than the right parent value. Right children will contain a value greater
than the right parent's value. Since, each node has either two children or three children, that's
why it is called 2-3 trees. It is a heightbalanced tree, and the reason is all the leaf nodes will
be at the same level. Since, it looks like a binary search tree it also has very good time
complexity in terms of searching the element. The real-life application of this data structure
is into string files in file systems and database systems. In the worst case, a binary search tree
can cost O(n) operation if the height of the tree is near equal to the number of elements, but
in the case of a 2-3 tree, there will be O(log N) time complexity.
Program:
#include <stdio.h>
#include <stdlib.h>
};
// Function to create a new node struct Node* createNode(int data)
newNode;
// Function to split a 4-node into two 2-nodes void splitNode(struct Node* parent,
struct Node* child, int data, struct Node* newChild) { if (data < child->data1) {
>data2 = -1;
} else { newChild-
>data1 = data;
>middle = NULL;
parent->data1; parent->data1 =
newChild->data1; parent->right
= parent->middle; parent-
>middle = newChild;
= newChild->data1; parent->right =
newChild->data1) { parent->data1 =
newChild->data1; parent->right =
parent->middle; parent->middle =
newChild;
} else { parent->data1 =
parent->data2; parent->data2 =
parent->data1; parent->data1 =
newChild->data1; parent->right
= parent->middle; parent-
>middle = newChild;
}
}
createNode(data);
>middle);
return root;
if (root) { inorder(root-
>data1); if (root->data2 != -
>data2);
inorder(root->middle);
inorder(root->right);
root = NULL;
int data;
char choice;
do { printf("Enter data to insert: ");
return 0;
OUTPUT:
DESCRIPTION:
There are several types of heaps, however in this chapter, we are going to discuss binary
heap. A binary heap is a data structure, which looks similar to a complete binary tree.
Heap data structure obeys ordering properties discussed below. Generally, a Heap is
represented by an array. In this chapter, we are representing a heap by H.
As the elements of a heap is stored in an array, considering the starting index as 1, the
position of the parent node of ith element can be found at ⌊ i/2 ⌋ . Left child and right child
of ith node is at position 2i and 2i + 1.
A binary heap can be classified further as either a max-heap or a min-heap based on the
ordering property.
Max-Heap
In this heap, the key value of a node is greater than or equal to the key value of the highest
child. Hence, H[Parent(i)] ≥ H[i]
Min-Heap
In mean-heap, the key value of a node is lesser than or equal to the key value of the lowest
child. Hence, H[Parent(i)] ≤ H[i]
In this context, basic operations are shown below with respect to Max-Heap. Insertion and
deletion of elements in and from heaps need rearrangement of elements. Hence, Heapify
function needs to be called.
PROGRAM:
#include <stdio.h>
int size = 0;
void swap(int *a, int
*b) { int temp = *b;
*b = *a;
*a = temp;
}
void heapify(int array[], int size, int i)
{ int largest = i; int l = 2 * i + 1;
int r = 2 * i + 2; if (l < size &&
array[l] > array[largest]) largest
= l;
if (r < size && array[r] >
array[largest]) largest = r; if
(largest != i) { swap(&array[i],
&array[largest]); heapify(array,
size, largest);
}
}
void insert(int array[], int newNum)
{ if (size == 0) {
PROGRAM:
#include<stdio.h> #include<stdlib.h> struct Edge; struct Vertex {
int info; struct Vertex *nextVertex; /*next vertex in the linked list
};
deleteIncomingEdges(int u);
while(1) {
printf("\n1.Insert a Vertex\n");
printf("2.Insert an Edge\n");
printf("3.Delete a Vertex\n");
printf("4.Delete an Edge\n");
printf("5.Display\n");
printf("6.Exit\n");
scanf("%d", &choice);
switch(choice) { case 1:
case 3:
scanf("%d", &u);
deleteIncomingEdges(u);
4:
case 6:
exit(1);
default:
printf("\nWrong choice\n");
break;
}/*End of
switch*/ }/*End of
while*/ return 0;
insertVertex(int u) { struct
malloc(sizeof(struct Vertex));
tmp->info = u; tmp->nextVertex
= NULL; tmp->firstEdge =
= start;
while(ptr->nextVertex != NULL)
be deleted\n"); return;
} if(start->info == u)/* Vertex to be deleted is first
vertex of list*/
{
tmp = start; start = start->nextVertex }
*/
{ q=
start;
>nextVertex->info == u)
break;
q = q->nextVertex;
if(q->nextVertex == NULL) {
q->nextVertex; q->nextVertex
= tmp->nextVertex;
}}
/*Before freeing the node tmp, free all edges going from this
free(tmp);
}/*End of deleteVertex()*/
void deleteIncomingEdges(int
if(ptr->firstEdge->destVertex->info == u) {
>firstEdge->nextEdge; free(tmp);
q = ptr->firstEdge; while(q-
>nextEdge->destVertex->info == u) {
tmp->nextEdge;
free(tmp);
continue;
q = q->nextEdge;
ptr = ptr->nextVertex;
}/*End of while*/
}/*End of
deleteIncomingEdges()*/ struct
Vertex *findVertex(int u) {
if(ptr->info == u ) { loc
} else ptr =
ptr->nextVertex;
loc = NULL;
return loc;
}/*End of findVertex()*/
*tmp;
locu = findVertex(u);
locv = findVertex(v);
}
tmp = malloc(sizeof(struct Edge));
>nextEdge = NULL;
if(locu->firstEdge == NULL)
{ locu->firstEdge = tmp;
return;
}/*End of insertEdge()*/
locu = findVertex(u);
if(locu == NULL ) {
return;
if(locu->firstEdge == NULL) {
return;
}
if(locu->firstEdge->destVertex->info == v)
>firstEdge = locu->firstEdge->nextEdge;
free(tmp); return;
q = locu->firstEdge; while(q-
>nextEdge->destVertex->info == v) {
tmp->nextEdge;
free(tmp);
return;
q = q->nextEdge;
void display(){
ptr = start;
while(ptr!=NULL)
printf("%d ->",ptr-
>info); q = ptr-
>firstEdge;
while(q!=NULL)
{
printf(" %d",q->destVertex-
>info); q = q->nextEdge; }
}/*End of display()*/
OUTPUT:
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1 -> 2
2 ->
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
1 -> 2
2 -> 3
3 -> 4
4 -> 5
5 ->
1.Insert a Vertex
2.Insert an Edge
3.Delete a Vertex
4.Delete an Edge
5.Display
6.Exit
Enter your choice : 6
EXPERIMENT NO: 06
Create a recursive function that takes the index of the node and a visited array.
PROGRAM:
#include <stdio.h>
#include
<stdlib.h> struct
node { int
vertex; struct
node* next;
};
};
addEdge(graph, 2, 3);
printGraph(graph);
DFS(graph, 2);
return 0; }
return newNode;
int i;
= 0;
} return
graph; }
newNode->next = graph->adjLists[dest];
int v;
adjList; graph->visited[vertex] = 1;
>vertex; if (graph-
>visited[connectedVertex] == 0) {
= temp->next; }}
OUTPUT:
Adjacency list of vertex 0
2 -> 1 ->
2 -> 0 ->
2 ->
Visited 2
Visited 3
Visited 1
Visited 0
EXPERIMENT NO: 07
Implement Breadth First Search for a graph non recursively
DESCRIPTION:
BFS algorithm
A standard BFS implementation puts each vertex of the graph into one of two categories:
1.Visited
2.Not Visited
The purpose of the algorithm is to mark each vertex as visited while avoiding cycles.
The algorithm works as follows:
1.Start by putting any one of the graph's vertices at the back of a queue.
2.Take the front item of the queue and add it to the visited list.
3.Create a list of that vertex's adjacent nodes. Add the ones which aren't in the visited list to
the back of the queue.
4.Keep repeating steps 2 and 3 until the queue is empty.
PROGRAM:
#include <stdio.h> int n, i, j, visited[10],
0; visited[i] = 0;
}
printf("Enter graph data in matrix
OUTPUT:
Enter the number of vertices: 4
4452
2619
9547
1380
1 2 3 4
EXPERIMENT NO: 08
Step5: Add the chosen edge to the MST if it does not form any cycle.
PROGRAM
#include<stdio.h>
#include<stdbool.h>
#define INF
9999999 #define V
5 int G[V][V] = {
sizeof(selected)); no_edge = 0;
printf("Edge : Weight\n");
while (no_edge < V - 1) { int
min = INF; x = 0; y = 0;
j < V; j++) { if
min = G[i][j]; x = i;
y = j; } }
printf("%d - %d : %d\n", x, y,
no_edge++;
return 0;
OUTPUT:
Edge : Weight
0-1:9
1 - 2 : 45
2 - 4 : 66
4 - 3 : 31
EXPERIMENT NO : 09
Implement Krushkal’s algorithm to generate a min-cost spanning tree.
AIM:Implement Krushkal’s algorithm to generate a min-cost spanning tree
ALGORITHM:
1. Sort all the edges in non-decreasing order of their weight.
2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far.
If the cycle is not formed, include this edge. Else, discard it. 3. Repeat step#2 until
there are (V-1) edges in the spanning tree.
PROGRAM
#include <stdio.h>
#define MAX 30
int u, v, w; } edge;
typedef struct
edge_list { edge
data[MAX];
int n;
} edge_list;
edge_list elist;
int Graph[MAX][MAX], n;
(Graph[i][j] != 0) {
elist.data[elist.n].u = i;
elist.data[elist.n].v = j;
elist.data[elist.n].w = Graph[i][j];
elist.n++;
if (cno1 != cno2) {
spanlist.data[spanlist.n] = elist.data[i];
spanlist.n = spanlist.n + 1;
vertexno) { return
(belongs[vertexno]);
} void applyUnion(int belongs[], int c1,
int c2) {
n; i++) if
(belongs[i] == c2)
belongs[i] = c1;
} void
sort() {
int i, j;
1] = temp; }
i, j, total_cost; n
= 6;
Graph[0][0] = 0;
Graph[0][1] = 42;
Graph[0][2] = 41;
Graph[0][3] = 0;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;
Graph[1][0] = 47;
Graph[1][1] = 0;
Graph[1][2] = 27;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 0;
Graph[1][6] = 0;
Graph[2][0] = 46;
Graph[2][1] = 21;
Graph[2][2] = 0;
Graph[2][3] = 32;
Graph[2][4] = 41;
Graph[2][5] = 0;
Graph[2][6] = 0;
Graph[3][0] = 0;
Graph[3][1] = 0;
Graph[3][2] = 33;
Graph[3][3] = 0;
Graph[3][4] = 3;
Graph[3][5] = 0;
Graph[3][6] = 0;
Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 44;
Graph[4][3] = 33;
Graph[4][4] = 0;
Graph[4][5] = 0; Graph[4][6] = 0;
Graph[5][0] = 0;
Graph[5][1] = 0;
Graph[5][2] = 8;
Graph[5][3] = 0;
Graph[5][4] = 16;
Graph[5][5] = 0;
Graph[5][6] = 0;
kruskalAlgo();
print(); }
OUTPUT:
5-2:8
5 - 4 : 16
2 - 1 : 21
3 - 2 : 33
2 - 0 : 46
1. The Prefix Function (Π): The Prefix Function, Π for a pattern encapsulates knowledge
about how the pattern matches against the shift of itself. This information can be used to
avoid a useless shift of the pattern 'p.' In other words, this enables avoiding backtracking
of the string 'S.' 2. The KMP Matcher: With string 'S,' pattern 'p' and prefix function 'Π'
as inputs, find the occurrence of 'p' in 'S' and returns the number of shifts of 'p' after
which occurrences are found.
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
= 0;
computeLPSArray(pat, M, lps);
}
else if (i < N && pat[j] != txt[i])
{ if (j != 0)
j = lps[j - 1];
else i=i+
1; } } free(lps); }
lps[0] = 0; i = 1;
while (i < M) { if
(pat[i] == pat[len]) {
len++; lps[i] =
len; i++; }
else { if (len !=
0) { len =
{ lps[i] = 0;
i++; } }
} int
main() {
char *txt =
"HIIHOWAREYOUWHATAREYOUDOING"; char
0;
OUTPUT:
Found pattern at index 12
EXPERIMENT NO : 12
Implement Knuth-Morris-Pratt algorithm for pattern matching.
PROGRAM:
# include <limits.h>
# include <string.h>
# include <stdio.h>
size, int
badchar[NO_OF_CHARS])
int i;
badchar[(int) str[i]] = i;
}
{ int m =
strlen(pat); int n
= strlen(txt);
int badchar[NO_OF_CHARS];
j--;
if (j < 0)
badchar[txt[s+m]] : 1;
} else s += max(1, j
- badchar[txt[s+j]]);
"HIMYSELFDINISHA"; char
return 0; }
OUTPUT:
pattern occurs at shift = 2