0% found this document useful (0 votes)
2 views

Data Structures Lab Manual Modified

good

Uploaded by

reddiee2222
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Data Structures Lab Manual Modified

good

Uploaded by

reddiee2222
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 87

DATA STRUCTURES

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)creation ii)insertion iii)deletion iv)traversal

3. write a program that uses functions to perform the following


operations on circular linked list:

i)creation ii)insertion iii)deletion iv)traversal

4. write a program that implement stack(its operations) using

i)arrays ii)pointers
5. write c program that implement Queue(its operations) using

i)Array ii)Pointers

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

7. write a program to implement the tree traversal methods

8. write a program to implement the


i) Binary Search tree ii)B tree iii) B+ tree
iv)AVL tree v)Red-Black tree

9. write a program to implement the graph traversal methods

10. Implement a Pattern matching algorithms using Boyer-Moore,


Knuth-Morris-Pratt

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);
}
}
}

/*Function to create a new circular linked list*/


void create()
{
int c;
x = (struct node*)malloc(sizeof(struct node));
printf("\n Enter the data:");
scanf("%d", &x->data);
x->link = x;
head = x;
printf("\n If you wish to continue press 1 otherwise 0:");
scanf("%d", &c);
while (c != 0)
{
y = (struct node*)malloc(sizeof(struct node));
printf("\n Enter the data:");
scanf("%d", &y->data);
x->link = y;
y->link = head;
x = y;
printf("\n If you wish to continue press 1 otherwise 0:");
scanf("%d", &c);
}
}
/*Function to insert an element at the begining of the list*/
void ins_at_beg()
{
x = head;
y = (struct node*)malloc(sizeof(struct node));
printf("\n Enter the data:");
scanf("%d", &y->data);
while (x->link != head)

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;
}

/*Function to delete an element at any begining of the list*/


void del_at_beg()

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);
}
}

/*Function to delete an element at any position the list*/

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);
}
}

/*Function to display the elements in the list*/

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

4-i) Stack implementation using Arrays

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");
}
}

/* Pop Operation on stack */


int pop()
{
int n;
if (top == NULL)
{
printf("\n stack is empty");
return 0;
}
else
{
n = top->data;
top= top->next;
return 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

5-i) QUEUE implementation using Array

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

6-i) Quick sort


AIM:
To implement C program that implements the Quick sort method to sort a given list of
integers in ascending order
DESCRIPTIOIN:
The arrangement of data in a preferred order is called sorting in the data structure. By sorting
data, it is easier to search through it quickly and easily. The simplest example of sorting is a
dictionary. ... It is the same panic an engineer will go through if their data is not sorted and
structured.
PROGRAM:
// Quick sort in C
#include <stdio.h>
// function to swap elements
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
// function to find the partition position
int partition(int array[], int low, int high)
{
// select the rightmost element as pivot
int pivot = array[high];
// pointer for greater element
int i = (low - 1);
// traverse each element of the array
// compare them with the pivot
for (int j = low; j < high; j++) {
if (array[j] <= pivot)
{
// if element smaller than pivot is found
// swap it with the greater element pointed by i
i++;
// swap element at i with element at j
swap(&array[i], &array[j]);
}
}

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);
}
}

// Print the array


void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
// Driver program
int main() {
int arr[] = {6, 5, 12, 10, 9, 1};
int size = sizeof(arr) / sizeof(arr[0]);

mergeSort(arr, 0, size - 1);


printf("Sorted array: \n");
printArray(arr, size);
}

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);

printf(" %3d", tree->data);


post(tree->right);
}
}
void main()
{
int op;
int ch;
printf("Binary Search Tree Ops:\n");
printf("1.Insertion\n2.Post Order 3.Pre Order4.In Order\n5.Exit\n");
while(1)
{
printf("\nEnter Your Option :");
scanf("%d", &op);
switch(op)
{
case 1: printf("Entre Data and type 0 To Exit:\n");
scanf("%d", &ch);
while(ch !=0)
{
tree = insert(tree, ch);
scanf("%d", &ch);
}
continue;
case 2: post(tree);
break;

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

8 i) Binary Search tree


AIM To Implement a C program to the Binary Search tree .
DESCRIPTION A binary search tree (BST) is a data structure where each node has at most two
children, with values smaller on the left and larger on the right. It offers efficient searching,
insertion, and deletion, making it suitable for tasks like data storage and retrieval.
PROGRAM:
// Binary Search Tree operations in C
#include <stdio.h>
#include <stdlib.h>
struct node {
int key;
struct node *left, *right;
};
// Create a node
struct node *newNode(int item) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// Inorder Traversal
void inorder(struct node *root) {
if (root != NULL) {
// Traverse left
inorder(root->left);
// Traverse root
printf("%d -> ", root->key);
// Traverse right
inorder(root->right);
}
}
// Insert a node
struct node *insert(struct node *node, int key) {
// Return a new node if the tree is empty
if (node == NULL) return newNode(key);
// Traverse to the right place and insert the node
if (key < node->key)
node->left = insert(node->left, key);

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;

if (pos > MIN)


median = MIN + 1;
else
median = MIN;
*newNode = (struct BTreeNode*)malloc(sizeof(struct BTreeNode));
j = median + 1;
while (j <= MAX) {
(*newNode)->val[j - median] = node->val[j];
(*newNode)->link[j - median] = node->link[j];
j++;
}
node->count = median;
(*newNode)->count = MAX - median;

if (pos <= MIN) {


insertNode(val, pos, node, child);
} else {
insertNode(val, pos - median, *newNode, child);
}
*pval = node->val[node->count];
(*newNode)->link[0] = node->link[node->count];
node->count--;
}
// Set the value
int setValue(int val, int *pval,
struct BTreeNode *node, struct BTreeNode **child) {
int pos;
if (!node) {
*pval = val;
*child = NULL;
return 1;
}
if (val< node->val[1]) {
pos = 0;
} else {
for (pos = node->count;
(val< node->val[pos] && pos > 1); pos--)

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;

flag = setValue(val, &i, root, &child);


if (flag)
root = createNode(i, child);
}
// Search node
void search(int val, int *pos, struct BTreeNode *myNode) {
if (!myNode) {
return;
}
if (val<myNode->val[1]) {
*pos = 0;
} else {
for (*pos = myNode->count;
(val<myNode->val[*pos] && *pos > 1); (*pos)--)
;
if (val == myNode->val[*pos]) {
printf("%d is found", val);
return;
}

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);

record *makeRecord(int value);


node *makeNode(void);
node *makeLeaf(void);
int getLeftIndex(node *parent, node *left);
node *insertIntoLeaf(node *leaf, int key, record *pointer);
node *insertIntoLeafAfterSplitting(node *root, node *leaf, int key,
record *pointer);
node *insertIntoNode(node *root, node *parent,
int left_index, int key, node *right);
node *insertIntoNodeAfterSplitting(node *root, node *parent,
int left_index,
int key, node *right);
node *insertIntoParent(node *root, node *left, int key, node *right);
node *insertIntoNewRoot(node *left, int key, node *right);
node *startNewTree(int key, record *pointer);
node *insert(node *root, int key, int value);

// 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;
}

// Print the leaves


void printLeaves(node *const root) {
if (root == NULL) {
printf("Empty tree.\n");
return;
}
int i;
node *c = root;
while (!c->is_leaf)
c = c->pointers[0];
while (true) {
for (i = 0; i< c->num_keys; i++) {
if (verbose_output)
printf("%p ", c->pointers[i]);
printf("%d ", c->keys[i]);
}
if (verbose_output)
printf("%p ", c->pointers[order - 1]);
if (c->pointers[order - 1] != NULL) {
printf(" | ");
c = c->pointers[order - 1];
} else
break;
}
printf("\n");
}
// Calculate height
int height(node *const root) {
int h = 0;
node *c = root;
while (!c->is_leaf) {
c = c->pointers[0];
h++;
}
return h;
}

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
}
}

// Find the range


int findRange(node *const root, int key_start, int key_end, bool verbose,
int returned_keys[], void *returned_pointers[]) {
int i, num_found;
num_found = 0;
node *n = findLeaf(root, key_start, verbose);
if (n == NULL)
return 0;
for (i = 0; i< n->num_keys&& n->keys[i] <key_start; i++)
if (i == n->num_keys)
return 0;
while (n != NULL) {
for (; i< n->num_keys&& n->keys[i] <= key_end; i++) {
returned_keys[num_found] = n->keys[i];
returned_pointers[num_found] = n->pointers[i];
num_found++;
}
n = n->pointers[order - 1];
i = 0;
}
return num_found;
}
// Find the leaf
node *findLeaf(node *const root, int key, bool verbose) {
if (root == NULL) {
if (verbose)
printf("Empty tree.\n");
return root;
}
int i = 0;
node *c = root;
while (!c->is_leaf) {
if (verbose) {
printf("[");
for (i = 0; i< c->num_keys - 1; i++)
printf("%d ", c->keys[i]);
printf("%d] ", c->keys[i]);

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;
}

record *find(node *root, int key, bool verbose, node **leaf_out) {


if (root == NULL) {
if (leaf_out != NULL) {
*leaf_out = NULL;
}
return NULL;
}

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;

y->height = max(height(y->left), height(y->right)) + 1;


x->height = max(height(x->left), height(x->right)) + 1;
return x;
}
// Left rotate
struct Node *leftRotate(struct Node *x) {
struct Node *y = x->right;
struct Node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
return y;
}
// Get the balance factor
int getBalance(struct Node *N) {
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
// Insert node
struct Node *insertNode(struct Node *node, int key) {
// Find the correct position to insertNode the node and insertNode it
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insertNode(node->left, key);
else if (key > node->key)
node->right = insertNode(node->right, key);
else
return node;
// Update the balance factor of each node and
// Balance the tree
node->height = 1 + max(height(node->left),
height(node->right));
int balance = getBalance(node);
if (balance > 1 && key < node->left->key)
return rightRotate(node);

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--;
}
}
}

// Print the inorder traversal of the tree


void inorderTraversal(struct rbNode *node) {
if (node) {
inorderTraversal(node->link[0]);
printf("%d ", node->data);
inorderTraversal(node->link[1]);
}
return;
}

// 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

AIM:To implement C program to implement the graph traversal methods:


DESCRIPTIOIN:
Breadth First Search (BFS) algorithm traverses a graph in a breadthward motion and uses a
queue to remember to get the next vertex to start a search, when a dead end occurs in any iteration.
As in the example given above, BFS algorithm traverses from A to B to E to F first then to C and
G lastly to D.
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);
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;

while (j >= 0 && pattern[j] == text[shift + j]) {


j--;
}
if (j < 0) {
printf("Pattern found at index %d\n", shift);

// To find multiple occurrences, you can continue searching by shifting


// the pattern further in the text.
shift += (shift + patternLength<textLength) ?patternLength - badCharTable[(int)
text[shift + 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

// C Program to Implement the KMP Pattern Searching Algorithm


#include <stdio.h>
#include <string.h>
#include <ctype.h>

void inputLine(char *line, int maxLen)


{
fflush(stdin);
int i = 0;
char c;
while ((c = getchar()) != '\n' && i < maxLen)
{
line[i++] = tolower(c);
}
line[i] = '\0';
}

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

You might also like