Data Structures Lab Manual Modified
Data Structures Lab Manual Modified
LAB MANUAL
II B.TECH – I SEM
1
INDEX
S.NO: Name Of the program Pg.no
1. write a program that uses functions to perform the following
operations on singly linked list:
i)creation ii)insertion iii)deletion iv)traversal
2. write a program that uses functions to perform the following
operations on doubly linked list:
i)arrays ii)pointers
5. write c program that implement Queue(its operations) using
i)Array ii)Pointers
2
1. Write a program that uses functions to perform the following operations on singly linked
list.
i) creation ii) insertion iii) deletion iv) Traversal
AIM:
To implement functions to perform the following operations on singly linked list by using C
program
i) creation ii) insertion iii) deletion iv) Ttraversal
DESCRIPTIOIN:
A singly linked list is a type of linked list that is unidirectional, that is, it can be traversed in only
one direction from head to the last node (tail). ... A single node contains data and a pointer to the
next node which helps in maintaining the structure of the list.
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
/*declaring a structure to create a node*/
struct node
{
int data;
struct node *next;
};
struct node *start;
/* inserting nodes into the list*/
/*function to insert values from beginning of the the single linked list*/
void insertbeg(void)
{
struct node *nn;
int a;
/*allocating implicit memory to the node*/
nn=(struct node *)malloc(sizeof(struct node));
printf("enter data:");
scanf("%d",&nn->data);
a=nn->data;
if(start==NULL) /*checking if List is empty*/
{
nn->next=NULL;
start=nn;
}
else
{
nn->next=start;
start=nn;
}
printf("%d succ. inserted\n",a);
3
return;
}
/*function to insert values from the end of the linked list*/
void insertend(void) {
struct node *nn,*lp;int b;
nn=(struct node *)malloc(sizeof(struct node));
printf("enter data:");
scanf("%d",&nn->data);
b=nn->data;
if(start==NULL)
{
nn->next=NULL;
start=nn;
}
else
{
lp=start;
while(lp->next!=NULL)
{
lp=lp->next;
}
lp->next=nn;
nn->next=NULL;
}
printf("%d is succ. inserted\n",b);
return;
}
/*function to insert values from the middle of the linked list*/
void insertmid(void) {
struct node *nn,*temp,*ptemp;int x,v;
nn=(struct node *)malloc(sizeof(struct node));
if(start==NULL)
{
printf("sll is empty\n"); return;
}
printf("enter data before which no. is to be inserted:\n");
scanf("%d",&x);
if(x==start->data)
{
insertbeg();
return;
4
ptemp=start;
temp=start->next;
while(temp!=NULL&&temp->data!=x)
{
ptemp=temp;
temp=temp->next;
}
if(temp==NULL)
{
printf("%d data does not exist\n",x);
}
else
{
printf("enter data:");
scanf("%d",&nn->data);
v=nn->data;
ptemp->next=nn;
nn->next=temp;
printf("%d succ. inserted\n",v);
}
return;
}
/*deletion operation*/
void deletion(void)
{
struct node *pt,*t;
int x;
if(start==NULL)
{
printf("sll is empty\n");
return;
}
printf("enter data to be deleted:");
scanf("%d",&x);
if(x==start->data)
{
t=start;
/* assigning first node pointer to next nod pointer to delete a data
from the starting of the node*/
start=start->next;
free(t);
printf("%d is succ. deleted\n",x);
return;
}
pt=start;
5
t=start->next;
while(t!=NULL&&t->data!=x)
{
pt=t;t=t->next;
}
if(t==NULL)
{
printf("%d does not exist\n",x);return;
}
else
{
pt->next=t->next;
}
printf("%d is succ. deleted\n",x);
free(t);
return;
}
void display(void)
{
struct node *temp;
if(start==NULL)
{
printf("sll is empty\n");
return;
}
printf("elements are:\n");
temp=start;
while(temp!=NULL)
{
printf("%d\n",temp->data);
temp=temp->next;
}
return;
}
/* main program*/
int main()
{
int c,a; start=NULL;
do
{
printf("1:insert\n2:delete\n3:display\n4:exit\nenter choice:");
scanf("%d",&c);
switch(c)
{
case 1: printf("1:insertbeg\n2:insert end\n3:insert mid\nenter choice:");
6
scanf("%d",&a);
switch(a)
{
case 1:insertbeg(); break;
case 2:insertend(); break;
case 3:insertmid(); break;
}
break;
case 2:deletion(); break;
case 3:display(); break;
case 4:printf("program ends\n");break;
default:printf("wrong choice\n");
break;
}
}while(c!=4);return 0;
}
OUTPUT:
7
2. Write a program that uses functions to perform the following operations on doubly
linked list:
i) creation ii) insertion iii) deletion iv) traversal
AIM:
To implement C program that uses functions to perform the following operations on doubly
linked list:
i) creation ii) insertion iii) deletion iv)traversal
DESCRIPTIOIN:
A doubly linked list is a linked data structure that consists of a set of sequentially linked
records called nodes. Each node contains three fields: two link fields (references to the previous
and to the next node in the sequence of nodes) and one data field.
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
/*declaring a structure to create a node*/
struct node
{
struct node *prev;
int data;
struct node *next;
};
struct node *start,*nt;
/* inserting nodes into the list*/
/*function to insert values from beginning of the the double linked list*/
void insertbeg(void)
{
int a;
struct node *nn,*temp;
/*allocating implicit memory to the node*/
nn=(struct node *)malloc(sizeof(struct node));
printf("enter data:");
scanf("%d",&nn->data);
a=nn->data;
if(start==NULL) /*checking if List is empty*/
{
nn->prev=nn->next=NULL;
start=nn;
}
else
{
nn->next=start;
nn->prev=NULL;
start->prev=nn;
start=nn;
}
printf("%d succ inserted \n",a);
8
}
/*function to insert values from the end of the linked list*/
void insertend(void)
{
int b;
struct node *nn,*lp;
nn=(struct node *)malloc(sizeof(struct node));
printf("enter data:");
scanf("%d",&nn->data);
b=nn->data;
if(start==NULL)
{
/* assigning first node pointer to next nod pointer to delete a data from the starting
of the node*/
nn->prev=nn->next=NULL;
start=nn;
}
else
{
lp=start;
while(lp->next!=NULL)
{
lp=lp->next;
}
nn->prev=lp;
lp->next=nn;
nn->next=NULL;
}
printf("%d succ inserted\n",b);
}
/*function to insert values from the middle of the linked list*/
void insertmid(void)
{
struct node *nn,*temp,*ptemp;
int x,c;
if(start==NULL)
{
printf("dll is empty\n");
return;
}
printf("enter data before which nn is to be inserted\n");
scanf("%d",&x);
if(x==start->data)
{
insertbeg();
}
9
ptemp=start;
temp=start->next;
while(temp->next!=NULL&&temp->data!=x)
{
ptemp=temp;
temp=temp->next;
}
if(temp==NULL)
{
printf("%d does not exit\n",x);
}
else
{
/*allocating implicit memory to the node*/
nn=(struct node *)malloc(sizeof(struct node));
printf("enter data");
scanf("%d",&nn->data);
c=nn->data;
nn->data;
nn->prev=ptemp;
nn->next=temp;
ptemp->next=nn;
temp->prev=nn;
printf("%d succ inserted\n",c);
}
}
/*end of insertion operation*/
/*deletion operation*/
void deletion() {
struct node *pt,*t;
int x;
t=pt=start;
if(start==NULL)
{
printf("dll is empty\n");
}
printf("enter data to be deleted:");
scanf("%d",&x);
if(x==start->data)
{
t=start;
t=t->next;
free(start);
start=t;
start=pt;
}
10
else {
while(t->next!=NULL&&t->data!=x)
{
pt=t; /*logic for traversing*/
t=t->next;
}
if(t->next==NULL&&t->data==x)
{
free(t);
pt->next=NULL;
}
else {
if(t->next==NULL&&t->data!=x)
printf("data not found");
else
{
pt->next=t->next;
free(t);
}
}
printf("%d is succ deleted\n",x);
}
}
/*end of deletion operation*/
/*display operation*/
void display()
{
struct node *temp;
if(start==NULL)
printf("stack is empty ");
temp=start;
while(temp->next!=NULL)
{
printf("%d",temp->data);
temp=temp->next;
}
printf("%d",temp->data);
}
/*end of display operation*/
/*main program*/
int main()
{
int c,a;
start=NULL;
do
{
11
printf("1.insert\n2.delete\n3.display\n4.exit\nenter choice:");
scanf("%d",&c);
switch(c)
{
case 1:printf("1.insertbeg\n2.insertend\n3.insertmid\nenter choice:");
scanf("%d",&a);
switch(a)
{
case 1:insertbeg();
break;
case 2:insertend();
break;
case 3:insertmid();
break;
}
break;
case 2:deletion();
break;
case 3:display();
break;
case 4:printf("program ends\n");
break;
default:printf("wrong choice\n");
break;
}
}
while(c!=4);
return 0;
}
12
OUTPUT:
13
3. Write a program that uses functions to perform the following operations on circular
linked list:
i) creation ii) insertion iii)deletion iv)traversal
AIM:
To implement C program that uses functions to perform the following operations on circular
linked list:
i)creation ii)insertion iii)deletion iv)traversal
DESCRIPTIOIN:
A circular linked list is a sequence of elements in which every element has a link to its next
element in the sequence and the last element has a link to the first element.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *link;
};
struct node *head = NULL, *x, *y, *z;
void create();
void ins_at_beg();
void ins_at_pos();
void del_at_beg();
void del_at_pos();
void traverse();
void main()
{
int ch;
printf("\n 1.Creation \n 2.Insertion at beginning \n 3.Insertion at remaining");
printf("\n4.Deletion at beginning \n5.Deletion at remaining \n6.traverse");
while (1)
{
printf("\n Enter your choice:");
scanf("%d", &ch);
switch(ch)
{
case 1:
create();
break;
case 2:
ins_at_beg();
break;
case 3:
ins_at_pos();
break;
case 4:
14
del_at_beg();
break;
case 5:
del_at_pos();
break;
case 6:
traverse();
break;
default:
exit(0);
}
}
}
15
{
x = x->link;
}
x->link = y;
y->link = head;
head = y;
}
/*Function to insert an element at any position the list*/
void ins_at_pos()
{
struct node *ptr;
int c = 1, pos, count = 1;
y = (struct node*)malloc(sizeof(struct node));
if (head == NULL)
{
printf("cannot enter an element at this place");
}
printf("\n Enter the data:");
scanf("%d", &y->data);
printf("\n Enter the position to be inserted:");
scanf("%d", &pos);
x = head;
ptr = head;
while (ptr->link != head)
{
count++;
ptr = ptr->link;
}
count++;
if (pos > count)
{
printf("OUT OF BOUND");
return;
}
while (c < pos)
{
z = x;
x = x->link;
c++;
}
y->link = x;
z->link = y;
}
16
{
if (head == NULL)
printf("\n List is empty");
else
{
x = head;
y = head;
while (x->link != head)
{
x = x->link;
}
head = y->link;
x->link = head;
free(y);
}
}
void del_at_pos()
{
if (head == NULL)
printf("\n List is empty");
else
{
int c = 1, pos;
printf("\n Enter the position to be deleted:");
scanf("%d", &pos);
x = head;
while (c < pos)
{
y = x;
x = x->link;
c++;
}
y->link = x->link;
free(x);
}
}
void traverse()
{
if (head == NULL)
printf("\n List is empty");
17
else
{
x = head;
while (x->link != head)
{
printf("%d->", x->data);
x = x->link;
}
printf("%d", x->data);
}
}
OUTPUT:
18
4. Write a program that implement stack (its operations) using
i) Arrays ii)pointers
AIM:
To implement C program that implement stack (its operations) using
i) arrays ii)pointers
DESCRIPTIOIN:
It means insertion and deletion in the stack data structure can be done only from the top of the
stack. You can access only the top of the stack at any given point in time. Inserting a new
element in the stack is termed a push operation. Removing or deleting elements from the stack is
termed pop operation.
PROGRAM:
#include<stdio.h>
int stack[100],choice,n,top,x,i;
void push(void);
void pop(void);
void display(void);
int main()
{
//clrscr();
top=-1;
printf("\n Enter the size of STACK:");
scanf("%d",&n);
printf("\n\t STACK OPERATIONS USING ARRAY");
printf("\n\t--------------------------------");
printf("\n\t 1.PUSH\n\t 2.POP\n\t 3.DISPLAY\n\t 4.EXIT");
do
{
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
printf("\n\t EXIT POINT ");
19
break;
default:
printf ("\n\t Please Enter a Valid Choice(1/2/3/4)");
}
}
while(choice!=4);
return 0;
}
void push()
{
if(top>=n-1)
{
printf("\n\tSTACK is over flow");
}
else
{
printf(" Enter a value to be pushed:");
scanf("%d",&x);
top++;
stack[top]=x;
}
}
void pop()
{
if(top<=-1)
{
printf("\n\t Stack is under flow");
}
else
{
printf("\n\t The popped elements is %d",stack[top]);
top--;
}
}
void display()
{
if(top>=0)
{
printf("\n The elements in STACK \n");
for(i=top; i>=0; i--)
printf("\n%d",stack[i]);
printf("\n Press Next Choice");
}
else
{
printf("\n The STACK is empty");
20
}
output:
21
4-ii) Stack implementation using pointers
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node1;
node1 *top = NULL;
/* Push data into stack */
void push()
{
node1 *temp;
int n;
printf("enter the element to be pushed\n");
scanf("%d",&n);
temp = (node1*)malloc(sizeof(node1));
temp->data = n;
temp->next=NULL;
if (top == NULL)
{
top = temp;
}
else
{
temp->next = top;
top = temp;
}
}
/* Display stack elements */
void display()
{
node1 *temp;
if (top== NULL)
{
printf("Stack is empty");
}
else
{
printf("the elements in the stack are\n");
22
temp = top;
while (temp!= NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
}
void main()
{
int n,ch;
while (1)
{
printf("\n 1 - Push");
printf("\n 2 - Pop");
printf("\n 3 - Dipslay");
printf("\n 4 - Exit");
printf("\n Enter choice : ");
scanf("%d", &ch);
switch (ch)
{
case 1:
push();
break;
case 2:
n=pop();
23
printf("the deleated elememt is%d\n",n );
break;
case 3:
display();
break;
case 4:
exit(0);
default :
printf(" Wrong choice, Please enter correct choice ");
break;
}
}
getch();
}
24
5. Write c program that implement Queue(its operations) using
i)Array ii)Pointers
AIM:
To implement C program that implement Queue(its operations) using QUEUE implementation
using Array
DESCRIPTIOIN:
To implement a queue using array, create an array arr of size n and take two variables front and
rear both of which will be initialized to 0 which means the queue is currently empty. Element rear
is the index upto which the elements are stored in the array and front is the index of the first element
of the array.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#define n 5
void main()
{
int queue[n],ch=1,front=0,rear=0,i,j=1,x=n;
clrscr();
printf("Queue using Array");
printf("\n1.Insertion \n2.Deletion \n3.Display \n4.Exit");
while(ch)
{
printf("\nEnter the Choice:");
scanf("%d",&ch);
switch(ch)
{
case 1:
if(rear==x)
printf("\n Queue is Full");
else
{
printf("\n Enter no %d:",j++);
scanf("%d",&queue[rear++]);
}
break;
case 2:
if(front==rear)
{
printf("\n Queue is empty");
}
else
{
printf("\n Deleted Element is %d",queue[front++]);
25
x++;
}
break;
case 3:
printf("\n Queue Elements are:\n ");
if(front==rear)
printf("\n Queue is Empty");
else
{
for(i=front; i<rear; i++)
{
printf("%d",queue[i]);
printf("\n");
}
}
break;
case 4:
exit(0);
default:
printf("Wrong Choice: please see the options");
}
}
}
getch();
}
output:
26
5-ii) Queue implementation using pointer
AIM:
To implement C program that implement Queue (its operations) using Queue implementation
using pointer
DESCRIPTIOIN:
In the linked queue, there are two pointers maintained in the memory i.e. front pointer and rear
pointer. ... The front pointer contains the address of the starting element of the queue while the
rear pointer contains the address of the last element of the queue.
PROGRAM:
#include <stdio.h>
struct linear_queue
{
int info;
struct linear_queue *next;
}*front,*rear,*newnode,*ptr;
void menu();
void display();
int underflow();
void enqueue(int);
void dequeue();
void main()
{
menu();
}
void menu()
{
int choice,item;
printf("MENU");
printf("\n1. Insert into the queue");
printf("\n2. Delete from queue");
printf("\n3. Display");
printf("\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the item tobe inserted: ");
scanf("%d",&item);
enqueue(item);
printf("\nAfter inserting queue is:\n");
display();
menu();
break;
case 2:
if(underflow()==1)
27
{
dequeue();
if(underflow()==1)
{
printf("\nAfter deletion queue is:\n");
display();
}
}
menu();
break;
case 3:
if(underflow()==1)
{
printf("The queue is:\n");
display();
}
menu();
break;
case 4:
exit(1);
default:
printf("Your choice is wrong\n\n");
menu();
}
}
int underflow()
{
if((front==NULL)&&(rear==NULL))
{
printf("\nQueue is empty");
return(0);
}
else
{
return(1);
}
}
void enqueue(int item)
{
newnode=(struct linear_queue*)malloc(sizeof(struct linear_queue));
newnode->info=item;
if((front==NULL)&&(rear==NULL))
{
front=newnode;
rear=newnode;
newnode->next=NULL;
28
}
else
{
rear->next=newnode;
newnode->next=NULL;
rear=newnode;
}
}
void dequeue()
{
if(front==rear)
{
front=NULL;
rear=NULL;
}
else
{
front=front->next;
}
}
void display()
{
int i;
ptr=front;
i=1;
while(ptr!=NULL)
{
printf("\nNode %d : %d",i,ptr->info);
ptr=ptr->next;
i++;
}
}
29
OUTPUT
30
6. Write a program that implements the following sorting methods to sort
a given list of integers in ascending order
i) Quick sort ii) Heap sort iii)Merge sort
31
// swap the pivot element with the greater element at i
swap(&array[i + 1], &array[high]);
// return the partition point
return (i + 1);
}
void quickSort(int array[], int low, int high) {
if (low < high) {
// find the pivot element such that
// elements smaller than pivot are on left of pivot
// elements greater than pivot are on right of pivot
int pi = partition(array, low, high);
// recursive call on the left of pivot
quickSort(array, low, pi - 1);
// recursive call on the right of pivot
quickSort(array, pi + 1, high);
}
}
// function to print array elements
void printArray(int array[], int size) {
for (int i = 0; i< size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}
// main function
int main() {
int data[] = {8, 7, 2, 1, 0, 9, 6};
int n = sizeof(data) / sizeof(data[0]);
printf("Unsorted Array\n");
printArray(data, n);
// perform quicksort on data
quickSort(data, 0, n - 1);
printf("Sorted array in ascending order: \n");
printArray(data, n);
}
32
OUTPUT:
33
6-ii)-Heap Sort
AIM:
To implement C program that implements the Heap sort method to sort a given list of integers
in ascending order
PROGRAM:
// Heap Sort in C
#include <stdio.h>
// Function to swap the the position of two elements
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void heapify(int arr[], int n, int i) {
// Find largest among root, left child and right child
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
// Swap and continue heapifying if root is not largest
if (largest != i) {
swap(&arr[i], &arr[largest]);
heapify(arr, n, largest);
}
}
// Main function to do heap sort
void heapSort(int arr[], int n) {
// Build max heap
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// Heap sort
for (int i = n - 1; i >= 0; i--) {
swap(&arr[0], &arr[i]);
// Heapify root element to get highest element at root again
heapify(arr, i, 0);
}
}
34
// Print an array
void printArray(int arr[], int n) {
for (int i = 0; i < n; ++i)
printf("%d ", arr[i]);
printf("\n");
}
// Driver code
int main() {
int arr[] = {1, 12, 9, 5, 6, 10};
int n = sizeof(arr) / sizeof(arr[0]);
heapSort(arr, n);
printf("Sorted array is \n");
printArray(arr, n);
}
OUTPUT:
35
6-iii)-Merge Sort
AIM:To implement C program that implements the Merge sort method to sort a given list of
integers in ascending order
PROGRAM:
// Merge sort in C
#include <stdio.h>
// Merge two subarrays L and M into arr
void merge(int arr[], int p, int q, int r)
{
// Create L ← A[p..q] and M ← A[q+1..r]
int n1 = q - p + 1;
int n2 = r - q;
int L[n1], M[n2];
for (int i = 0; i < n1; i++)
L[i] = arr[p + i];
for (int j = 0; j < n2; j++)
M[j] = arr[q + 1 + j];
// Maintain current index of sub-arrays and main array
int i, j, k;
i = 0;
j = 0;
k = p;
// Until we reach either end of either L or M, pick larger among
// elements L and M and place them in the correct position at A[p..r]
while (i < n1 && j < n2) {
if (L[i] <= M[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = M[j];
j++;
}
k++;
}
// When we run out of elements in either L or M,
// pick up the remaining elements and put in A[p..r]
while (i < n1) {
arr[k] = L[i];
i++;
k++;
36
} while (j < n2)
{
arr[k] = M[j];
j++;
k++;
}
}
// Divide the array into two subarrays, sort them and merge them
void mergeSort(int arr[], int l, int r) {
if (l < r) {
// m is the point where the array is divided into two subarrays
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
// Merge the sorted subarrays
merge(arr, l, m, r);
}
}
37
OUTPUT:
38
7. Write a program to implement the tree traversal methods.
AIM:
To implement C a program to implement the tree traversal methods.
DESCRIPTIOIN:
In computer science, tree traversal (also known as tree search and walking the tree) is a form of
graph traversal and refers to the process of visiting (checking and/or updating)each node in a
tree data structure, exactly once. Such traversals are classified by the order in which the nodes are
visited
PROGRAM:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct node1
{
int data;
struct node1 *left;
struct node1 *right;
};
typedef struct node1 node;
node *tree = NULL;
node *insert(node *tree, char val)
{
if(tree == NULL)
{
tree = (node *)malloc(sizeof(node));
tree->left = NULL;
tree->right = NULL;
tree->data = val;
return (tree);
}
else
{
if(val < tree->data)
tree->left = insert(tree, val);
else
tree->right = insert(tree, val);
return (tree);
}
}
void post(node *tree)
{
if(tree != NULL)
{
post(tree->left);
39
post(tree->right);
printf(" %3d", tree->data);
}
}
void pre(node *tree)
{
if(tree != NULL)
{
printf(" %3d", tree->data);
pre(tree->left);
pre(tree->right);
}
}
void inorder(node *tree)
{
if(tree != NULL)
{
post(tree->left);
40
case 3: pre(tree);
break;
case 4: inorder(tree);
break;
case 5: exit(0);
}
printf("\nMenu Repeats Itself Hit '3' To Exit\n");
}
getch();
}
OUTPUT
41
8. Write a program to implement the
i) Binary Search tree ii)B tree iii) B+ tree
iv) AVL tree v) Red-Black tree
42
else
node->right = insert(node->right, key);
return node;
}
// Find the inorder successor
struct node *minValueNode(struct node *node) {
struct node *current = node;
// Find the leftmost leaf
while (current && current->left != NULL)
current = current->left;
return current;
}
// Deleting a node
struct node *deleteNode(struct node *root, int key) {
// Return if the tree is empty
if (root == NULL) return root;
// Find the node to be deleted
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
// If the node is with only one child or no child
if (root->left == NULL) {
struct node *temp = root->right;
free(root);
return temp;
} else if (root->right == NULL) {
struct node *temp = root->left;
free(root);
return temp;
}
// If the node has two children
struct node *temp = minValueNode(root->right);
// Place the inorder successor in position of the node to be deleted
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
return root;
43
}
// Driver code
int main() {
struct node *root = NULL;
root = insert(root, 8);
root = insert(root, 3);
root = insert(root, 1);
root = insert(root, 6);
root = insert(root, 7);
root = insert(root, 10);
root = insert(root, 14);
root = insert(root, 4);
printf("Inorder traversal: ");
inorder(root);
printf("\nAfter deleting 10\n");
root = deleteNode(root, 10);
printf("Inorder traversal: ");
inorder(root);
}
OUT PUT
44
8 ii) B Tree
AIM: To Implement a C program to the B Tree .
DESCRIPTION: A B-tree is a balanced tree that organizes data efficiently for quick searching
and insertion. B-trees have a self-balancing property, ensuring that all leaf nodes are at the same
level, which helps maintain predictable performance even with large datasets.
PROGRAM:
// Searching a key on a B-tree in C
#include <stdio.h>
#include <stdlib.h>
#define MAX 3
#define MIN 2
struct BTreeNode {
int val[MAX + 1], count;
struct BTreeNode *link[MAX + 1];
};
struct BTreeNode *root;
// Create a node
struct BTreeNode *createNode(int val, struct BTreeNode *child) {
struct BTreeNode *newNode;
newNode = (struct BTreeNode*)malloc(sizeof(struct BTreeNode));
newNode->val[1] = val;
newNode->count = 1;
newNode->link[0] = root;
newNode->link[1] = child;
return newNode;
}
// Insert node
void insertNode(int val, int pos, struct BTreeNode *node,
struct BTreeNode *child) {
int j = node->count;
while (j > pos) {
node->val[j + 1] = node->val[j];
node->link[j + 1] = node->link[j];
j--;
}
node->val[j + 1] = val;
node->link[j + 1] = child;
node->count++;
}
// Split node
void splitNode(int val, int *pval, int pos, struct BTreeNode *node,
45
struct BTreeNode *child, struct BTreeNode **newNode) {
int median, j;
46
;
if (val == node->val[pos]) {
printf("Duplicates are not permitted\n");
return 0;
}
}
if (setValue(val, pval, node->link[pos], child)) {
if (node->count < MAX) {
insertNode(*pval, pos, node, *child);
} else {
splitNode(*pval, pval, pos, node, *child, child);
return 1;
}
}
return 0;
}
// Insert the value
void insert(int val) {
int flag, i;
struct BTreeNode *child;
47
}
search(val, pos, myNode->link[*pos]);
return;
}
// Traverse then nodes
void traversal(struct BTreeNode *myNode) {
int i;
if (myNode) {
for (i = 0; i<myNode->count; i++) {
traversal(myNode->link[i]);
printf("%d ", myNode->val[i + 1]);
}
traversal(myNode->link[i]);
}
}
int main() {
int val, ch;
insert(8);
insert(9);
insert(10);
insert(11);
insert(15);
insert(16);
insert(17);
insert(18);
insert(20);
insert(23);
traversal(root);
printf("\n");
search(11, &ch, root);
}
48
OUTPUT
49
8 iii) B+ Tree
AIM: To Implement a C program to the B+ Tree .
DESCRIPTION: A B+ tree is a self-balancing tree used for efficient data retrieval and range
queries. It stores data in its leaf nodes and uses internal nodes for navigation, making it excellent
for handling large datasets and optimizing search and range-based operations.
B+ TREE:
// Searching on a B+ Tree in C
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Default order
#define ORDER 3
typedef struct record {
int value;
} record;
// Node
typedef struct node {
void **pointers;
int *keys;
struct node *parent;
bool is_leaf;
int num_keys;
struct node *next;
} node;
int order = ORDER;
node *queue = NULL;
bool verbose_output = false;
// Enqueue
void enqueue(node *new_node);
// Dequeue
node *dequeue(void);
int height(node *const root);
int pathToLeaves(node *const root, node *child);
void printLeaves(node *const root);
void printTree(node *const root);
void findAndPrint(node *const root, int key, bool verbose);
void findAndPrintRange(node *const root, int range1, int range2, bool verbose);
int findRange(node *const root, int key_start, int key_end, bool verbose,
int returned_keys[], void *returned_pointers[]);
node *findLeaf(node *const root, int key, bool verbose);
50
record *find(node *root, int key, bool verbose, node **leaf_out);
int cut(int length);
// Enqueue
void enqueue(node *new_node) {
node *c;
if (queue == NULL) {
queue = new_node;
queue->next = NULL;
} else {
c = queue;
while (c->next != NULL) {
c = c->next;
}
c->next = new_node;
new_node->next = NULL;
}
}
// Dequeue
node *dequeue(void) {
node *n = queue;
queue = queue->next;
51
n->next = NULL;
return n;
}
52
// Get path to root
int pathToLeaves(node *const root, node *child) {
int length = 0;
node *c = child;
while (c != root) {
c = c->parent;
length++;
}
return length;
}
// Print the tree
void printTree(node *const root) {
node *n = NULL;
int i = 0;
int rank = 0;
int new_rank = 0;
if (root == NULL) {
printf("Empty tree.\n");
return;
}
queue = NULL;
enqueue(root);
while (queue != NULL) {
n = dequeue();
if (n->parent != NULL && n == n->parent->pointers[0]) {
new_rank = pathToLeaves(root, n);
if (new_rank != rank) {
rank = new_rank;
printf("\n");
}
}
if (verbose_output)
printf("(%p)", n);
for (i = 0; i< n->num_keys; i++) {
if (verbose_output)
printf("%p ", n->pointers[i]);
printf("%d ", n->keys[i]);
}
if (!n->is_leaf)
for (i = 0; i<= n->num_keys; i++)
53
enqueue(n->pointers[i]);
if (verbose_output) {
if (n->is_leaf)
printf("%p ", n->pointers[order - 1]);
else
printf("%p ", n->pointers[n->num_keys]);
}
printf("| ");
}
printf("\n");
}
// Find the node and print it
void findAndPrint(node *const root, int key, bool verbose) {
node *leaf = NULL;
record *r = find(root, key, verbose, NULL);
if (r == NULL)
printf("Record not found under key %d.\n", key);
else
printf("Record at %p -- key %d, value %d.\n",
r, key, r->value);
}
// Find and print the range
void findAndPrintRange(node *const root, int key_start, int key_end,
bool verbose) {
int i;
int array_size = key_end - key_start + 1;
int returned_keys[array_size];
void *returned_pointers[array_size];
int num_found = findRange(root, key_start, key_end, verbose,
returned_keys, returned_pointers);
if (!num_found)
printf("None found.\n");
else {
for (i = 0; i<num_found; i++)
printf("Key: %d Location: %p Value: %d\n",
returned_keys[i],
returned_pointers[i],
((record *)
returned_pointers[i])
->value);
54
}
}
55
}
i = 0;
while (i< c->num_keys) {
if (key >= c->keys[i])
i++;
else
break;
}
if (verbose)
printf("%d ->\n", i);
c = (node *)c->pointers[i];
}
if (verbose) {
printf("Leaf [");
for (i = 0; i< c->num_keys - 1; i++)
printf("%d ", c->keys[i]);
printf("%d] ->\n", c->keys[i]);
}
return c;
}
int i = 0;
node *leaf = NULL;
leaf = findLeaf(root, key, verbose);
for (i = 0; i< leaf->num_keys; i++)
if (leaf->keys[i] == key)
break;
if (leaf_out != NULL) {
*leaf_out = leaf;
}
if (i == leaf->num_keys)
return NULL;
56
else
return (record *)leaf->pointers[i];
}
int cut(int length) {
if (length % 2 == 0)
return length / 2;
else
return length / 2 + 1;
}
record *makeRecord(int value) {
record *new_record = (record *)malloc(sizeof(record));
if (new_record == NULL) {
perror("Record creation.");
exit(EXIT_FAILURE);
} else {
new_record->value = value;
}
return new_record;
}
node *makeNode(void) {
node *new_node;
new_node = malloc(sizeof(node));
if (new_node == NULL) {
perror("Node creation.");
exit(EXIT_FAILURE);
}
new_node->keys = malloc((order - 1) * sizeof(int));
if (new_node->keys == NULL) {
perror("New node keys array.");
exit(EXIT_FAILURE);
}
new_node->pointers = malloc(order * sizeof(void *));
if (new_node->pointers == NULL) {
perror("New node pointers array.");
exit(EXIT_FAILURE);
}
new_node->is_leaf = false;
new_node->num_keys = 0;
new_node->parent = NULL;
new_node->next = NULL;
57
return new_node;
}
node *makeLeaf(void) {
node *leaf = makeNode();
leaf->is_leaf = true;
return leaf;
}
int getLeftIndex(node *parent, node *left) {
int left_index = 0;
while (left_index<= parent->num_keys&&
parent->pointers[left_index] != left)
left_index++;
return left_index;
}
node *insertIntoLeaf(node *leaf, int key, record *pointer) {
int i, insertion_point;
insertion_point = 0;
while (insertion_point< leaf->num_keys&& leaf->keys[insertion_point] < key)
insertion_point++;
for (i = leaf->num_keys; i>insertion_point; i--) {
leaf->keys[i] = leaf->keys[i - 1];
leaf->pointers[i] = leaf->pointers[i - 1];
}
leaf->keys[insertion_point] = key;
leaf->pointers[insertion_point] = pointer;
leaf->num_keys++;
return leaf;
}
node *insertIntoLeafAfterSplitting(node *root, node *leaf, int key, record *pointer) {
node *new_leaf;
int *temp_keys;
void **temp_pointers;
int insertion_index, split, new_key, i, j;
new_leaf = makeLeaf();
temp_keys = malloc(order * sizeof(int));
if (temp_keys == NULL) {
perror("Temporary keys array.");
exit(EXIT_FAILURE);
}
58
temp_pointers = malloc(order * sizeof(void *));
if (temp_pointers == NULL) {
perror("Temporary pointers array.");
exit(EXIT_FAILURE);
}
insertion_index = 0;
while (insertion_index< order - 1 && leaf->keys[insertion_index] < key)
insertion_index++;
for (i = 0, j = 0; i< leaf->num_keys; i++, j++) {
if (j == insertion_index)
j++;
temp_keys[j] = leaf->keys[i];
temp_pointers[j] = leaf->pointers[i];
}
temp_keys[insertion_index] = key;
temp_pointers[insertion_index] = pointer;
leaf->num_keys = 0;
split = cut(order - 1);
for (i = 0; i< split; i++) {
leaf->pointers[i] = temp_pointers[i];
leaf->keys[i] = temp_keys[i];
leaf->num_keys++;
}
for (i = split, j = 0; i< order; i++, j++) {
new_leaf->pointers[j] = temp_pointers[i];
new_leaf->keys[j] = temp_keys[i];
new_leaf->num_keys++;
}
free(temp_pointers);
free(temp_keys);
new_leaf->pointers[order - 1] = leaf->pointers[order - 1];
leaf->pointers[order - 1] = new_leaf;
for (i = leaf->num_keys; i< order - 1; i++)
leaf->pointers[i] = NULL;
for (i = new_leaf->num_keys; i< order - 1; i++)
new_leaf->pointers[i] = NULL;
new_leaf->parent = leaf->parent;
new_key = new_leaf->keys[0];
return insertIntoParent(root, leaf, new_key, new_leaf);
}
59
node *insertIntoNode(node *root, node *n,
int left_index, int key, node *right) {
int i;
for (i = n->num_keys; i>left_index; i--) {
n->pointers[i + 1] = n->pointers[i];
n->keys[i] = n->keys[i - 1];
}
n->pointers[left_index + 1] = right;
n->keys[left_index] = key;
n->num_keys++;
return root;
}
node *insertIntoNodeAfterSplitting(node *root, node *old_node, int left_index,
int key, node *right) {
int i, j, split, k_prime;
node *new_node, *child;
int *temp_keys;
node **temp_pointers;
temp_pointers = malloc((order + 1) * sizeof(node *));
if (temp_pointers == NULL) {
exit(EXIT_FAILURE);
}
temp_keys = malloc(order * sizeof(int));
if (temp_keys == NULL) {
exit(EXIT_FAILURE);
}
for (i = 0, j = 0; i<old_node->num_keys + 1; i++, j++) {
if (j == left_index + 1)
j++;
temp_pointers[j] = old_node->pointers[i];
}
for (i = 0, j = 0; i<old_node->num_keys; i++, j++) {
if (j == left_index)
j++;
temp_keys[j] = old_node->keys[i];
}
temp_pointers[left_index + 1] = right;
temp_keys[left_index] = key;
split = cut(order);
new_node = makeNode();
60
old_node->num_keys = 0;
for (i = 0; i< split - 1; i++) {
old_node->pointers[i] = temp_pointers[i];
old_node->keys[i] = temp_keys[i];
old_node->num_keys++;
}
old_node->pointers[i] = temp_pointers[i];
k_prime = temp_keys[split - 1];
for (++i, j = 0; i< order; i++, j++) {
new_node->pointers[j] = temp_pointers[i];
new_node->keys[j] = temp_keys[i];
new_node->num_keys++;
}
new_node->pointers[j] = temp_pointers[i];
free(temp_pointers);
free(temp_keys);
new_node->parent = old_node->parent;
for (i = 0; i<= new_node->num_keys; i++) {
child = new_node->pointers[i];
child->parent = new_node;
}
return insertIntoParent(root, old_node, k_prime, new_node);
}
node *insertIntoParent(node *root, node *left, int key, node *right) {
int left_index;
node *parent;
parent = left->parent;
if (parent == NULL)
return insertIntoNewRoot(left, key, right);
left_index = getLeftIndex(parent, left);
if (parent->num_keys< order - 1)
return insertIntoNode(root, parent, left_index, key, right);
return insertIntoNodeAfterSplitting(root, parent, left_index, key, right);
}
node *insertIntoNewRoot(node *left, int key, node *right) {
node *root = makeNode();
root->keys[0] = key;
root->pointers[0] = left;
root->pointers[1] = right;
root->num_keys++;
61
root->parent = NULL;
left->parent = root;
right->parent = root;
return root;
}
node *startNewTree(int key, record *pointer) {
node *root = makeLeaf();
root->keys[0] = key;
root->pointers[0] = pointer;
root->pointers[order - 1] = NULL;
root->parent = NULL;
root->num_keys++;
return root;
}
node *insert(node *root, int key, int value) {
record *record_pointer = NULL;
node *leaf = NULL;
record_pointer = find(root, key, false, NULL);
if (record_pointer != NULL) {
record_pointer->value = value;
return root;
}
record_pointer = makeRecord(value);
if (root == NULL)
return startNewTree(key, record_pointer);
leaf = findLeaf(root, key, false);
if (leaf->num_keys< order - 1) {
leaf = insertIntoLeaf(leaf, key, record_pointer);
return root;
}
return insertIntoLeafAfterSplitting(root, leaf, key, record_pointer);
}
int main() {
node *root;
char instruction;
root = NULL;
root = insert(root, 5, 33);
root = insert(root, 15, 21);
root = insert(root, 25, 31);
root = insert(root, 35, 41);
62
root = insert(root, 45, 10);
printTree(root);
findAndPrint(root, 15, instruction = 'a');
}
OUTPUT
63
8 iv) AVL Tree
AIM: To Implement a C program to the AVL Tree .
DESCRIPTION: An AVL tree is a self-balancing binary search tree where the height difference
between its left and right subtrees (known as the balance factor) is 1. This balance ensures efficient
insertion, deletion, and searching operations.
PROGRAM:
// AVL tree implementation in C
#include <stdio.h>
#include <stdlib.h>
// Create Node
struct Node {
int key;
struct Node *left;
struct Node *right;
int height;
};
int max(int a, int b);
// Calculate height
int height(struct Node *N) {
if (N == NULL)
return 0;
return N->height;
}
int max(int a, int b) {
return (a > b) ? a : b;
}
// Create a node
struct Node *newNode(int key) {
struct Node *node = (struct Node *)
malloc(sizeof(struct Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}
// Right rotate
struct Node *rightRotate(struct Node *y) {
struct Node *x = y->left;
struct Node *T2 = x->right;
x->right = y;
64
y->left = T2;
65
if (balance < -1 && key > node->right->key)
return leftRotate(node);
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
struct Node *minValueNode(struct Node *node) {
struct Node *current = node;
while (current->left != NULL)
current = current->left;
return current;
}
// Delete a nodes
struct Node *deleteNode(struct Node *root, int key) {
// Find the node and delete it
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
if ((root->left == NULL) || (root->right == NULL)) {
struct Node *temp = root->left ? root->left : root->right;
if (temp == NULL) {
temp = root;
root = NULL;
} else
*root = *temp;
free(temp);
} else {
struct Node *temp = minValueNode(root->right);
root->key = temp->key;
66
root->right = deleteNode(root->right, temp->key);
}
}
if (root == NULL)
return root;
// Update the balance factor of each node and
// balance the tree
root->height = 1 + max(height(root->left),
height(root->right));
int balance = getBalance(root);
if (balance > 1 &&getBalance(root->left) >= 0)
return rightRotate(root);
if (balance > 1 &&getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
if (balance < -1 &&getBalance(root->right) <= 0)
return leftRotate(root);
if (balance < -1 &&getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// Print the tree
void printPreOrder(struct Node *root) {
if (root != NULL) {
printf("%d ", root->key);
printPreOrder(root->left);
printPreOrder(root->right);
}
}
int main() {
struct Node *root = NULL;
root = insertNode(root, 2);
root = insertNode(root, 1);
root = insertNode(root, 7);
root = insertNode(root, 4);
root = insertNode(root, 5);
root = insertNode(root, 3);
67
root = insertNode(root, 8);
printPreOrder(root);
root = deleteNode(root, 3);
printf("\nAfter deletion: ");
printPreOrder(root);
return 0;
}
OUTPUT
68
8 v) RED-BLACK TREE
AIM: To Implement a C program to the Red-Black Tree .
DESCRIPTION: A Red-Black Tree is a self-balancing binary search tree. It ensures that the tree
remains approximately balanced by adhering to certain rules, including coloring nodes either red
or black and following specific balancing criteria during insertion and deletion operations. Red-
Black Trees are commonly used in data structures like sets and maps.
PROGRAM:
// Implementing Red-Black Tree in C
#include <stdio.h>
#include <stdlib.h>
enum nodeColor {
RED,
BLACK
};
struct rbNode {
int data, color;
struct rbNode *link[2];
};
struct rbNode *root = NULL;
// Create a red-black tree
struct rbNode *createNode(int data) {
struct rbNode *newnode;
newnode = (struct rbNode*)malloc(sizeof(struct rbNode));
newnode->data = data;
newnode->color = RED;
newnode->link[0] = newnode->link[1] = NULL;
return newnode;
}
// Insert an node
void insertion(int data) {
struct rbNode *stack[98], *ptr, *newnode, *xPtr, *yPtr;
int dir[98], ht = 0, index;
ptr = root;
if (!root) {
root = createNode(data);
return;
}
stack[ht] = root;
dir[ht++] = 0;
while (ptr != NULL) {
if (ptr->data == data) {
69
printf("Duplicates Not Allowed!!\n");
return;
}
index = (data - ptr->data) >0 ?1 : 0;
stack[ht] = ptr;
ptr = ptr->link[index];
dir[ht++] = index;
}
stack[ht - 1]->link[index] = newnode = createNode(data);
while ((ht>= 3) && (stack[ht - 1]->color == RED)) {
if (dir[ht - 2] == 0) {
yPtr = stack[ht - 2]->link[1];
if (yPtr != NULL &&yPtr->color == RED) {
stack[ht - 2]->color = RED;
stack[ht - 1]->color = yPtr->color = BLACK;
ht = ht - 2;
} else {
if (dir[ht - 1] == 0) {
yPtr = stack[ht - 1];
} else {
xPtr = stack[ht - 1];
yPtr = xPtr->link[1];
xPtr->link[1] = yPtr->link[0];
yPtr->link[0] = xPtr;
stack[ht - 2]->link[0] = yPtr;
}
xPtr = stack[ht - 2];
xPtr->color = RED;
yPtr->color = BLACK;
xPtr->link[0] = yPtr->link[1];
yPtr->link[1] = xPtr;
if (xPtr == root) {
root = yPtr;
} else {
stack[ht - 3]->link[dir[ht - 3]] = yPtr;
}
break;
}
} else {
yPtr = stack[ht - 2]->link[0];
70
if ((yPtr != NULL) && (yPtr->color == RED)) {
stack[ht - 2]->color = RED;
stack[ht - 1]->color = yPtr->color = BLACK;
ht = ht - 2;
} else {
if (dir[ht - 1] == 1) {
yPtr = stack[ht - 1];
} else {
xPtr = stack[ht - 1];
yPtr = xPtr->link[0];
xPtr->link[0] = yPtr->link[1];
yPtr->link[1] = xPtr;
stack[ht - 2]->link[1] = yPtr;
}
xPtr = stack[ht - 2];
yPtr->color = BLACK;
xPtr->color = RED;
xPtr->link[1] = yPtr->link[0];
yPtr->link[0] = xPtr;
if (xPtr == root) {
root = yPtr;
} else {
stack[ht - 3]->link[dir[ht - 3]] = yPtr;
}
break;
}
}
}
root->color = BLACK;
}
// Delete a node
void deletion(int data) {
struct rbNode *stack[98], *ptr, *xPtr, *yPtr;
struct rbNode *pPtr, *qPtr, *rPtr;
int dir[98], ht = 0, diff, i;
enumnodeColor color;
if (!root) {
printf("Tree not available\n");
return;
71
}
ptr = root;
while (ptr != NULL) {
if ((data - ptr->data) == 0)
break;
diff = (data - ptr->data) >0 ?1 : 0;
stack[ht] = ptr;
dir[ht++] = diff;
ptr = ptr->link[diff];
}
if (ptr->link[1] == NULL) {
if ((ptr == root) && (ptr->link[0] == NULL)) {
free(ptr);
root = NULL;
} else if (ptr == root) {
root = ptr->link[0];
free(ptr);
} else {
stack[ht - 1]->link[dir[ht - 1]] = ptr->link[0];
}
} else {
xPtr = ptr->link[1];
if (xPtr->link[0] == NULL) {
xPtr->link[0] = ptr->link[0];
color = xPtr->color;
xPtr->color = ptr->color;
ptr->color = color;
if (ptr == root) {
root = xPtr;
} else {
stack[ht - 1]->link[dir[ht - 1]] = xPtr;
}
dir[ht] = 1;
stack[ht++] = xPtr;
} else {
i = ht++;
while (1) {
dir[ht] = 0;
stack[ht++] = xPtr;
72
yPtr = xPtr->link[0];
if (!yPtr->link[0])
break;
xPtr = yPtr;
}
dir[i] = 1;
stack[i] = yPtr;
if (i> 0)
stack[i - 1]->link[dir[i - 1]] = yPtr;
yPtr->link[0] = ptr->link[0];
xPtr->link[0] = yPtr->link[1];
yPtr->link[1] = ptr->link[1];
if (ptr == root) {
root = yPtr;
}
color = yPtr->color;
yPtr->color = ptr->color;
ptr->color = color;
}
}
if (ht< 1)
return;
if (ptr->color == BLACK) {
while (1) {
pPtr = stack[ht - 1]->link[dir[ht - 1]];
if (pPtr&&pPtr->color == RED) {
pPtr->color = BLACK;
break;
}
if (ht< 2)
break;
if (dir[ht - 2] == 0) {
rPtr = stack[ht - 1]->link[1];
if (!rPtr)
break;
if (rPtr->color == RED) {
stack[ht - 1]->color = RED;
rPtr->color = BLACK;
stack[ht - 1]->link[1] = rPtr->link[0];
rPtr->link[0] = stack[ht - 1];
73
if (stack[ht - 1] == root) {
root = rPtr;
} else {
stack[ht - 2]->link[dir[ht - 2]] = rPtr;
}
dir[ht] = 0;
stack[ht] = stack[ht - 1];
stack[ht - 1] = rPtr;
ht++;
rPtr = stack[ht - 1]->link[1];
}
if ((!rPtr->link[0] || rPtr->link[0]->color == BLACK) &&
(!rPtr->link[1] || rPtr->link[1]->color == BLACK)) {
rPtr->color = RED;
} else {
if (!rPtr->link[1] || rPtr->link[1]->color == BLACK) {
qPtr = rPtr->link[0];
rPtr->color = RED;
qPtr->color = BLACK;
rPtr->link[0] = qPtr->link[1];
qPtr->link[1] = rPtr;
rPtr = stack[ht - 1]->link[1] = qPtr;
}
rPtr->color = stack[ht - 1]->color;
stack[ht - 1]->color = BLACK;
rPtr->link[1]->color = BLACK;
stack[ht - 1]->link[1] = rPtr->link[0];
rPtr->link[0] = stack[ht - 1];
if (stack[ht - 1] == root) {
root = rPtr;
} else {
stack[ht - 2]->link[dir[ht - 2]] = rPtr;
}
break;
}
} else {
rPtr = stack[ht - 1]->link[0];
if (!rPtr)
break;
74
if (rPtr->color == RED) {
stack[ht - 1]->color = RED;
rPtr->color = BLACK;
stack[ht - 1]->link[0] = rPtr->link[1];
rPtr->link[1] = stack[ht - 1];
if (stack[ht - 1] == root) {
root = rPtr;
} else {
stack[ht - 2]->link[dir[ht - 2]] = rPtr;
}
dir[ht] = 1;
stack[ht] = stack[ht - 1];
stack[ht - 1] = rPtr;
ht++;
rPtr = stack[ht - 1]->link[0];
}
if ((!rPtr->link[0] || rPtr->link[0]->color == BLACK) &&
(!rPtr->link[1] || rPtr->link[1]->color == BLACK)) {
rPtr->color = RED;
} else {
if (!rPtr->link[0] || rPtr->link[0]->color == BLACK) {
qPtr = rPtr->link[1];
rPtr->color = RED;
qPtr->color = BLACK;
rPtr->link[1] = qPtr->link[0];
qPtr->link[0] = rPtr;
rPtr = stack[ht - 1]->link[0] = qPtr;
}
rPtr->color = stack[ht - 1]->color;
stack[ht - 1]->color = BLACK;
rPtr->link[0]->color = BLACK;
stack[ht - 1]->link[0] = rPtr->link[1];
rPtr->link[1] = stack[ht - 1];
if (stack[ht - 1] == root) {
root = rPtr;
} else {
stack[ht - 2]->link[dir[ht - 2]] = rPtr;
}
break;
75
}
}
ht--;
}
}
}
// Driver code
int main() {
int ch, data;
while (1) {
printf("1. Insertion\t2. Deletion\n");
printf("3. Traverse\t4. Exit");
printf("\nEnter your choice:");
scanf("%d", &ch);
switch (ch) {
case 1:
printf("Enter the element to insert:");
scanf("%d", &data);
insertion(data);
break;
case 2:
printf("Enter the element to delete:");
scanf("%d", &data);
deletion(data);
break;
case 3:
inorderTraversal(root);
printf("\n");
break;
76
case 4:
exit(0);
default:
printf("Not available\n");
break;
}
printf("\n");
}
return 0;
}
77
OUTPUT
78
9. Write a program to implement the graph traversal methods:
9-i): Depth First Traversal.
AIM:To implement C program to implement the graph traversal methods:
DESCRIPTIOIN:
Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data
structures. The algorithm starts at the root node (selecting some arbitrary node as the root node
in the case of a graph) and explores as far as possible along each branch before backtracking.
PROGRAM:
#include <stdio.h>
#include <conio.h>
void dfs(int x, int visited[], int a[][10], int n)
{
int j;
visited[x] = 1;
printf("%3d", x);
for(j = 1; j <= n; j++)
{
if((a[x][j] == 1) && (visited[j] == 0))
dfs(j, visited, a, n);
}
}
void main()
{
int a[10][10];
int i, j, n;
int visited[10];
clrscr();
printf("Depth First Traversal\n");
printf("\nEnter The Node:");
scanf("%d", &n);
for(i = 1; i <= n ; i++)
{
for(j = 1; j <= n; j++)
{
printf("\nEnter 1 If There's An Edge B/W %d & %d: ", i, j);
scanf("%d", &a[i][j]);
}
}
printf("\nThe Adjacency Matrix Is:\n");
for(i = 1; i <= n ; i++)
{
for(j = 1; j <= n; j++)
{
printf("%3d", a[i][j]);
79
}
printf("\n");
}
for(i = 1; i <= n ; i++)
visited[i] = 0;
printf("\nEnter The Starting Node For Traversal:");
scanf("%d", &i);
printf("\n The Traversal From %d Is:\n", i);
if(visited[i] == 0)
dfs(i, visited, a, n);
getch();
}
OUTPUT:
80
9-ii): Breadth First Traversal
#include <stdio.h>
#include <conio.h>
void dfs(int x, int visited[], int a[][10], int n)
{
int j;
visited[x] = 1;
printf("%3d", x);
rear++;
front++;
q[rear] = x;
while(front <= rear){
x = q[rear];
front++;
for(j = 1; j <= n; j++)
{
if((a[x][j] == 1) && (visited[j] == 0))
{
printf("%3d", x);
visited[j] = 1;
rear++;
q[rear] =j;
}
}
}
}
void main()
{
int a[10][10];
int i, j;
int visited[10];
clrscr();
printf("Breadth First Traversal\n");
printf("\nEnter The Node:");
scanf("%d", &n);
for(i = 1; i <= n ; i++)
81
{
for(j = 1; j <= n; j++)
{
printf("\nEnter 1 If There's An Edge B/W %d & %d", i, j);
scanf("%", &a[i][j]);
}
}
printf("\nThe Adjacency Matrix Is:\n");
for(i = 1; i <= n ; i++)
{
for(j = 1; j <= n; j++)
{
printf("%3d", a[i][j]);
}
printf("\n");
}
for(i = 1; i <= n ; i++)
visited[i] = o;
printf("\nEnter The Starting Node For Traversal:");
scanf("%d", &i);
printf("/n The Traversal From %d Is:\n", i);
if(visited[i] == 0)
bfs(i, visited, a, n);
getch();
}
OUTPUT:
82
10. Implement a Pattern matching algorithms using Boyer-Moore, Knuth-Morris-Pratt
10 i) Boyer-Moore
AIM: To implement Pattern matching algorithms using Boyer-Moore, Knuth-Morris-Pratt.
DESCRIPTION: Pattern matching algorithms are the methods used for finding specific sequences
of characters (patterns) within larger text or strings. Common algorithms include Brute Force,
Knuth-Morris-Pratt (KMP), and Boyer-Moore, each with its own way of efficiently searching for
patterns in text data.
PROGRAM
#include <stdio.h>
#include <string.h>
#define ALPHABET_SIZE 256
void computeBadCharacterTable(char *pattern, int patternLength, int
badCharTable[ALPHABET_SIZE]) {
int i;
for (i = 0; i< ALPHABET_SIZE; i++) {
badCharTable[i] = -1;
}
for (i = 0; i<patternLength; i++) {
badCharTable[(int) pattern[i]] = i;
}
}
void boyerMoore(char *text, char *pattern) {
int textLength = strlen(text);
int patternLength = strlen(pattern);
int badCharTable[ALPHABET_SIZE];
computeBadCharacterTable(pattern, patternLength, badCharTable);
int shift = 0;
while (shift <= (textLength - patternLength)) {
int j = patternLength - 1;
83
} else {
shift += (j - badCharTable[(int) text[shift + j]]) > 1 ? j - badCharTable[(int) text[shift + j]] : 1;
}
}
}
int main() {
char text[] = "A sample text with sample pattern matching.";
char pattern[] = "sample";
boyerMoore(text, pattern);
return 0;
}
OUTPUT
84
10 ii) Knuth-Morris-Pratt (KMP):
AIM: To implement Pattern matching algorithms using Boyer-Moore, Knuth-Morris-Pratt.
DESCRIPTION: Pattern matching algorithms are the methods used for finding specific
sequences of characters (patterns) within larger text or strings. Common algorithms include
Brute Force, Knuth-Morris-Pratt (KMP), and Boyer-Moore, each with its own way of efficiently
searching for patterns in text data.
PROGRAM
int main(void)
{
char word[100];
char mainString[100];
int i, j, k;
int wordLen, mainStringLen;
int skipTable[100];
int wordIndex, mainStringIndex;
printf("Enter the word: ");
inputLine(word, 100);
printf("Enter the main string: ");
inputLine(mainString, 100);
wordLen = strlen(word);
mainStringLen = strlen(mainString);
for (i = 0; i < wordLen; i++)
85
{
skipTable[i] = 1;
}
for (i = 1; i < wordLen; i++)
{
j = i - 1;
k = i;
while (j >= 0 && word[j] == word[k])
{
skipTable[k] = j + 1;
j--;
k--;
}
}
wordIndex = 0;
mainStringIndex = 0;
while (mainStringIndex < mainStringLen)
{
if (word[wordIndex] == mainString[mainStringIndex])
{
wordIndex++;
mainStringIndex++;
}
else
{
mainStringIndex += skipTable[wordIndex];
wordIndex = 0;
}
if (wordIndex == wordLen)
{
printf("The word is found at index %d\n", mainStringIndex - wordLen);
wordIndex = 0;
}
}
if (wordIndex != 0)
{
printf("The word is not found\n");
}
return 0;
}
86
OUTPUT
87