0% found this document useful (0 votes)
24 views113 pages

DAA Lab File 2[1]

Uploaded by

ashishkumarsws
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views113 pages

DAA Lab File 2[1]

Uploaded by

ashishkumarsws
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 113

PRANVEER SINGH INSTITUTE OF TECHNOLOGY, KANPUR

DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING

Odd Semester 2023-24

B. Tech.- Third Year

Semester- V

Lab File
Design and Analysis of Algorithm
(KCS553)

Submitted To : Submitted By :
Faculty Name : Mr. Pankaj Singh Yadav Name :
Designation : Assistant Professor Roll No. :
Section :
Table of Contents
• Vision and Mission Statements of the Institute

• Vision and Mission Statements of the Department

• PEOs, POs, PSOs of the Department

• Course Objective and Outcomes

• List of Experiments

• Index

Department Vision Statement


To be a recognized Department of Computer Science & Engineering that produces versatile computer engineers,
capable of adapting to the changing needs of computer and related industry.

Department Mission Statements


The mission of the Department of Computer Science and Engineering is:

i. To provide broad based quality education with knowledge and attitude to succeed in Computer Science &
Engineering careers.

ii. To prepare students for emerging trends in computer and related industry.

iii. To develop competence in students by providing them skills and aptitude to foster culture of continuous and
lifelong learning.

iv. To develop practicing engineers who investigate research, design, and find workable solutions to complex
engineering problems with awareness & concern for society as well as environment.

Program Educational Objectives (PEOs)


i. The graduates will be efficient leading professionals with knowledge of computer science & engineering
discipline that enables them to pursue higher education and/or successful careers in various domains.

ii. Graduates will possess capability of designing successful innovative solutions to real life problems that are
technically sound, economically viable and socially acceptable.

iii. Graduates will be competent team leaders, effective communicators and capable of working in
multidisciplinary teams following ethical values.

iv. The graduates will be capable of adapting to new technologies/tools and constantly upgrading their knowledge
and skills with an attitude for lifelong learning

Department Program Outcomes (POs)


The students of Computer Science and Engineering Department will be able:
1. Engineering knowledge: Apply the knowledge of mathematics, science, Computer Science & Engineering
fundamentals, and an engineering specialization to the solution of complex engineering problems.

2. Problem analysis: Identify, formulate, review research literature, and analyze complex engineering
problems reaching substantiated conclusions using first principles of mathematics, natural sciences, and
Computer Science & Engineering sciences.

3. Design/development of solutions: Design solutions for complex Computer Science & Engineering
problems and design system components or processes that meet the specified needs with appropriate
consideration for the public health and safety, and the cultural, societal, and environmental considerations.

4. Investigation: Use research-based knowledge and research methods including design of experiments,
analysis and interpretation of data, and synthesis of the information to provide valid conclusions.

5. Modern tool usage: Create, select, and apply appropriate techniques, resources, and modern engineering
and IT tools including prediction and modelling to complex Computer Science & Engineering activities with
an understanding of the limitations.

6. The Engineering and Society: Apply reasoning informed by the contextual knowledge to assess societal,
health, safety, legal and cultural issues and the consequent responsibilities relevant to the professional
engineering practice in the field of Computer Science and Engineering.

7. Environment and sustainability: Understand the impact of the professional Computer Science &
Engineering solutions in societal and environmental contexts, and demonstrate the knowledge of, and need for
sustainable development.

8. Ethics: Apply ethical principles and commit to professional ethics and responsibilities and norms of the
Computer Science & Engineering practice.

9. Individual and team work: Function effectively as an individual, and as a member or leader in diverse
teams, and in multidisciplinary settings.

10. Communication: Communicate effectively on complex Computer Science & Engineering activities with
the engineering community and with society at large, such as, being able to comprehend and write effective
reports and design documentation, make effective presentations, and give and receive clear instructions.

11. Project management and finance: Demonstrate knowledge and understanding of the Computer Science
& Engineering and management principles and apply these to one’s own work, as a member and leader in a
team, to manage projects and in multidisciplinary environments.

12. Life-long learning: Recognize the need for, and have the preparation and ability to engage in independent
and life-long learning in the broadest context of technological change.

Department Program Specific Outcomes (PSOs)


The students will be able to:

1. Use algorithms, data structures/management, software design, concepts of programming languages and
computer organization and architecture.

2. Understand the processes that support the delivery and management of information systems within a
specific application environment.

Course Outcomes
Level to be
*Level of Bloom’s Taxonomy Level to be met *Level of Bloom’s Taxonomy
Met
L1: Remember 1 L2: Understand 2
L3: Apply 3 L4: Analyze 4
L5: Evaluate 5 L6: Create 6

CO Number Course Outcomes


Implement algorithm to solve problems by iterative approach.
KCS-551.1
KCS-551.2 Implement algorithm to solve problems by divide and conquer approach

KCS-551.3 Implement algorithm to solve problems by Greedy algorithm approach.

Implement algorithm to solve problems by Dynamic programming, backtracking, branch and


KCS-551.4 bound approach.
KCS-551.5 Implement algorithm to solve problems by branch and bound approach

List of Experiments

Lab Lab Experiment Corresponding CO


No.
Implementation of analysis of linear and binary search using
1
recursive function
2 Implementation and analysis of Insertion , Bubble and Selection sort
3 Implementation and analysis of Merge and Quick sort
4 Implementation and analysis of Heap and Counting sort
5 Implementation and analysis of Radix and Shell sort
Implementation and anaylsis of Activity Selection Problem and
6
knapsack problem using greedy solution
Implementation and Analysis of 0/1 Knapsack problem using
7
dynamic programming method and LCS
8 Implementation of Kruskal’s and Prim’s algorithm to find MST
9 Implementation of Warshall’s and Dijkstra’s algorithm
Implementation of N- Queen problem and sum of subset problem
10
using backtracking
11 Implementation of Naïve String and Rabin Karp Matching Algorithm
Implementation to find all Hamiltonian cycle in a connected undirected
12
graph.
13 Implementation of Insertion operation in RB Tree

14 Implementation of Insertion operation of B-Tree

INDEX
S Lab Experiment Date of Date of Marks Faculty
No Experiment Submission Signature
a) Implementation of analysis of
1 Linear search using recursive
function 05/10/23 19/10/23
b) Implementation of analysis of
Binary search using recursive
function
a) Implementation and analysis of
2 Insertion sort
b) Implementation and analysis of 05/10/23 19/10/23
Bubble sort
c) Implementation and analysis of
Selection sort
a) Implementation and analysis of
3 Merge sort
b) Implementation and analysis of 19/10/23 26/10/23
Quick sort
a) Implementation and analysis of
4 Heap sort
b) Implementation and analysis of 19/10/23 26/10/23
Counting sort
a) Implementation and analysis of
5 Radix sort
b) Implementation and analysis of 26/10/23 31/10/23
Shell sort
a) Implementation and anaylsis of
6 Activity Selection Problem
b) Implementation and anaylsis of 26/10/23 31/10/23
knapsack problem using greedy
solution
a) Implementation and Analysis of 0/1
7 Knapsack problem using dynamic
programming method 31/10/23 06/11/23
b) Implementation and Analysis LCS
a) Implementation of Kruskal’s
8 algorithm to find MST
b) Implementation of Prim’s algorithm 06/11/23 19/11/23
to find MST
a) Implementation of Warshall’s
9 algorithm for all pair shortest path
b) Implementation of Dijkstra’s 19/11/23 26/11/23
algorithm for single source shortest
path
a) Implementation of N- Queen
10
problem using backtracking
b) Implementation of sum of subset 26/11/23 30/11/23
problem using backtracking
a) Implementation of Naïve String
11
Matching Algorithm
b) Implementation of Rabin Karp 30/11/23 05/12/23
Matching Algorithm

12 Implementation to find all Hamiltonian 05/12/23 12/12/23


cycle in a connected undirected graph.
13 Implementation of Insertion operation in 12/12/23 19/12/23
RB Tree

14 Implementation of Insertion operation of B- 19/12/23 25/12/23


Tree

Experiment No. :-1


Objective 1:- Implementation of Analysis of Linear Search using Recursive Function.

Pseudocode:-

Function:

RecursiveLinearSearch(array, startIndex, endIndex, key)


If startIndex > endIndex
Return -1 // Base case: key not found in the array

If array[startIndex] equals key


Return startIndex // Base case: key found at current index

Return RecursiveLinearSearch(array, startIndex + 1, endIndex, key) // Recursive call with updated


start index

Algorithm:-

int recursiveLinearSearch(int arr[], int startIndex, int endIndex, int key) {


// If start index is greater than end index, return -1 indicating key not found
if (startIndex > endIndex)
return -1;

// If key is found at the current index, return the index


if (arr[startIndex] == key)
return startIndex;

// Recursive call with updated start index


return recursiveLinearSearch(arr, startIndex + 1, endIndex, key);
}
arr[] is the array in which the search is performed.
startIndex is the starting index for the search.
endIndex is the ending index for the search.
key is the value being searched for.

Program:-

#include <stdio.h>
int RecursiveLS(int arr[], int value, int index, int n)
{
int pos = 0;

if(index >= n)
{
return 0;
}

else if (arr[index] == value)


{
pos = index + 1;
return pos;
}

else
{
return RecursiveLS(arr, value, index+1, n);
}
return pos;
}

int main()
{
int n, value, pos, m = 0, arr[100];
printf("Enter the total elements in the array ");
scanf("%d", &n);

printf("Enter the array elements\n");


for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}

printf("Enter the element to search ");


scanf("%d", &value);

pos = RecursiveLS(arr, value, 0, n);


if (pos != 0)
{
printf("Element found at pos %d ", pos);
}
else
{
printf("Element not found");
}
return 0;
}

Objective 2:- Implementation of Analysis of Binary Search using Recursive Function.

Pseudocode:-

Function:

RecursiveBinarySearch(array, left, right, key)


If right is greater than or equal to left
Set mid = left + (right - left) / 2
If array[mid] is equal to key
Return mid // Element found at the middle

If array[mid] is greater than key


Return RecursiveBinarySearch(array, left, mid - 1, key) // Search the left half
Return RecursiveBinarySearch(array, mid + 1, right, key) // Search the right half

Algorithm:-

int recursiveBinarySearch(int arr[], int left, int right, int key) {


if (right >= left) {
int mid = left + (right - left) / 2;

// If element is present at the middle itself


if (arr[mid] == key)
return mid;

// If element is smaller than mid, search the left subarray


if (arr[mid] > key)
return recursiveBinarySearch(arr, left, mid - 1, key);

// If element is larger than mid, search the right subarray


return recursiveBinarySearch(arr, mid + 1, right, key);
}

// If element is not present in the array


return -1;
}
arr[] is the sorted array where the search is performed.
left is the starting index of the search range.
right is the ending index of the search range.
key is the value being searched for.

Program:-

#include <stdio.h>
int recursiveBinarySearch(int array[], int start_index, int end_index, int element)
{
if (end_index >= start_index)
{
int middle = start_index + (end_index - start_index )/2;
if (array[middle] == element)
return middle;
if (array[middle] > element)
return recursiveBinarySearch(array, start_index, middle-1, element);
return recursiveBinarySearch(array, middle+1, end_index, element);
}
return -1;
}
int main(void)
{
int array[] = {1, 4, 7, 9, 16, 56, 70};
int n = 7;
int element = 9;
int found_index = recursiveBinarySearch(array, 0, n-1, element);
if(found_index == -1 )
{
printf("Element not found in the array ");
}
else
{
printf("Element found at index : %d",found_index);
}
return 0;
}

Experiment No. :-2

Objective 1:- Implementation and Analysis of Insertion Sort


Pseudocode:-

Function:
InsertionSort(array)
n = length of array
for i = 1 to n - 1
key = array[i]
j=i-1
// Move elements greater than key to one position ahead of their current position
while j >= 0 and array[j] > key
array[j + 1] = array[j]
j=j-1
array[j + 1] = key

Algorithm:-

• Start with the second element (or index 1) and consider it as the "key".
• Compare the key element with the elements before it in the sorted subarray.
• If the key element is smaller, shift the greater elements one position ahead to make space for the key
element.
• Repeat steps 2 and 3 until the key element is in its correct position within the sorted subarray.
• Move to the next element and repeat the process until the entire array is sorted.

Program:-

#include <stdio.h>
void printArray(int array[], int size)
{
for (int i = 0; i < size; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}

void insertionSort(int array[], int size)


{
for (int step = 1; step < size; step++)
{
int key = array[step];
int j = step - 1;
while (key < array[j] && j >= 0)
{
array[j + 1] = array[j];
--j;
}
array[j + 1] = key;
}
}
int main()
{
int data[] = {9, 5, 1, 4, 3};
int size = sizeof(data) / sizeof(data[0]);
insertionSort(data, size);
printf("Sorted array in ascending order:\n");
printArray(data, size);
}

Objective 2:- Implementation and Analysis of Bubble Sort

Pseudocode:-
procedure bubbleSort(A: list of sortable items)
n := length(A)

repeat
swapped := false
for i := 1 to n-1 inclusive do
if A[i-1] > A[i] then
swap A[i-1] and A[i]
swapped := true
end if
end for
until not swapped
end procedure
Algorithm:-
procedure bubbleSort(A: array of elements)
n := length(A)
swapped := true

while swapped
swapped := false
for i := 1 to n-1
if A[i-1] > A[i] then
swap A[i-1] and A[i]
swapped := true
end if
end for
end while
end procedure
Program:-
#include <stdio.h>
void bubbleSort(int array[], int size)
{
for (int step = 0; step < size - 1; ++step)
{
for (int i = 0; i < size - step - 1; ++i)
{
if (array[i] > array[i + 1])
{
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
}
}
}
void printArray(int array[], int size)
{
for (int i = 0; i < size; ++i)
{
printf("%d ", array[i]);
}
printf("\n");
}

int main()
{
int data[] = {-2, 45, 0, 11, -9};
int size = sizeof(data) / sizeof(data[0]);
bubbleSort(data, size);
printf("Sorted Array in Ascending Order:\n");
printArray(data, size);
}

Objective 3:- Implementation and Analysis of Selection Sort

Pseudocode:-
procedure selectionSort(A: array of elements)
n := length(A)

for i := 0 to n-1
// Assume the current index is the minimum
minIndex := i
// Find the index of the minimum element in the unsorted part of the array
for j := i+1 to n-1
if A[j] < A[minIndex] then
minIndex := j
end if
end for

// Swap the found minimum element with the element at index i


swap A[i] and A[minIndex]
end for
end procedure

Algorithm:-
procedure insertionSort(A: array of elements)
n := length(A)

for i := 1 to n-1
key := A[i]
j := i - 1

// Move elements that are greater than key to one position ahead
while j >= 0 and A[j] > key
A[j + 1] := A[j]
j := j - 1

// Insert key into the correct position in the sorted part of the array

Program:-
#include <stdio.h>
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void selectionSort(int array[], int size)
{
for (int step = 0; step < size - 1; step++)
{
int min_idx = step;
for (int i = step + 1; i < size; i++)
{
if (array[i] < array[min_idx])
min_idx = i;
}
swap(&array[min_idx], &array[step]);
}
}
void printArray(int array[], int size)
{
for (int i = 0; i < size; ++i)
{
printf("%d ", array[i]);
}
printf("\n");
}
int main()
{
int data[] = {20, 12, 10, 15, 2};
int size = sizeof(data) / sizeof(data[0]);
selectionSort(data, size);
printf("Sorted array in Acsending Order:\n");
printArray(data, size);
}
Experiment No. :- 3

Objective 1:- Implementation and analysis of Merge Sort

Pseudocode:-
MergeSort(arr):
if length of arr <= 1:
return arr
// Split the array into two halves
mid = length of arr / 2
left = arr[0 to mid-1]
right = arr[mid to end]

// Recursively sort each half


left = MergeSort(left)
right = MergeSort(right)

// Merge the sorted halves


merged = Merge(left, right)

return merged

Merge(left, right):
result = []
leftIndex = 0
rightIndex = 0

Algorithm:-

MergeSort(arr, left, right):


if left > right
return
mid = (left+right)/2
mergeSort(arr, left, mid)
mergeSort(arr, mid+1, right)
merge(arr, left, mid, right)
end

Program:-
// C program for Merge Sort
#include <stdio.h>
#include <stdlib.h>

// Merges two subarrays of arr[].


// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;

// Create temp arrays


int L[n1], R[n2];

// Copy data to temp arrays


// L[] and R[]
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];

// Merge the temp arrays back


// into arr[l..r]
// Initial index of first subarray
i = 0;

// Initial index of second subarray


j = 0;

// Initial index of merged subarray


k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
// Copy the remaining elements
// of L[], if there are any
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}

// Copy the remaining elements of


// R[], if there are any
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}

// l is for left index and r is


// right index of the sub-array
// of arr to be sorted
void mergeSort(int arr[], int l, int r)
{
if (l < r) {
// Same as (l+r)/2, but avoids
// overflow for large l and h
int m = l + (r - l) / 2;

// Sort first and second halves


mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);

merge(arr, l, m, r);
}
}

// UTILITY FUNCTIONS
// Function to print an array
void printArray(int A[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}

// Driver code
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);

printf("Given array is \n");


printArray(arr, arr_size);

mergeSort(arr, 0, arr_size - 1);

printf("\nSorted array is \n");


printArray(arr, arr_size);
return 0;
}

Objective 2:- Implementation and analysis of Quick Sort

Pseudocode:-

QuickSort(arr, low, high):


if low < high:
// Partition the array, and get the pivot index
pivotIndex = Partition(arr, low, high)

// Recursively sort the sub-arrays on both sides of the pivot


QuickSort(arr, low, pivotIndex - 1)
QuickSort(arr, pivotIndex + 1, high)

Partition(arr, low, high):


// Choose the rightmost element as the pivot
pivot = arr[high]

// Initialize the index of smaller element


smallerIndex = low - 1

// Traverse the array and rearrange elements relative to the pivot


for current in range(low to high - 1):
if arr[current] <= pivot:
// Swap arr[current] and arr[smallerIndex]
Swap(arr, current, smallerIndex + 1)
smallerIndex += 1

// Swap the pivot with the element at smallerIndex + 1


Swap(arr, high, smallerIndex + 1)

Algorithm:-

QuickSort(arr, low, high):


if low < high:
// Partition the array and get the pivot index
pivotIndex = Partition(arr, low, high)

// Recursively sort the sub-arrays on both sides of the pivot


QuickSort(arr, low, pivotIndex - 1)
QuickSort(arr, pivotIndex + 1, high)

Partition(arr, low, high):


// Choose the rightmost element as the pivot
pivot = arr[high]

// Initialize the index of the smaller element


smallerIndex = low - 1

// Traverse the array and rearrange elements relative to the pivot


for current in range(low to high - 1):
if arr[current] <= pivot:
// Swap arr[current] and arr[smallerIndex + 1]
Swap(arr, current, smallerIndex + 1)
smallerIndex += 1

// Swap the pivot with the element at smallerIndex + 1


Swap(arr, high, smallerIndex + 1)

// Return the index of the pivot element


return smallerIndex + 1

Swap(arr, i, j):
// Helper function to

Program:-
#include <stdio.h>

void merge(int arr[], int start, int mid, int end) {

int len1 = mid - start + 1;


int len2 = end - mid;

int leftArr[len1], rightArr[len2];

for (int i = 0; i < len1; i++)


leftArr[i] = arr[start + i];
for (int j = 0; j < len2; j++)
rightArr[j] = arr[mid + 1 + j];

int i, j, k;
i = 0;
j = 0;
k = start;

while (i < len1 && j < len2) {


if (leftArr[i] <= rightArr[j]) {
arr[k] = leftArr[i];
i++;
} else {
arr[k] = rightArr[j];
j++;
}
k++;
}

while (i < len1) {


arr[k] = leftArr[i];
i++;
k++;
}

while (j < len2) {


arr[k] = rightArr[j];
j++;
k++;
}
}

void mergeSort(int arr[], int start, int end) {


if (start < end) {

int mid = start + (end - start) / 2;


mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
merge(arr, start, mid, end);
}
}

void display(int arr[], int size) {


for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}

int main() {
int arr[] = {6, 5, 12, 10, 9, 1};
int size = sizeof(arr) / sizeof(arr[0]);

printf("Original array\n");
display(arr, size);

mergeSort(arr, 0, size - 1);

printf("Sorted array\n");
display(arr, size);
}
Experiment No. :- 4

Objective 1:- Implementation and analysis of Heap Sort

Pseudocode:-
procedure heapSort(arr):
n := length(arr)

// Build a max heap


for i from n / 2 - 1 down to 0:
heapify(arr, n, i)

// Extract elements one by one from the heap


for i from n - 1 down to 1:
// Swap the root (maximum element) with the last element
swap(arr[0], arr[i])

// Call heapify on the reduced heap


heapify(arr, i, 0)
procedure heapify(arr, n, i):
largest := i
left := 2 * i + 1
right := 2 * i + 2

// Check if left child is larger than the root


if left < n and arr[left] > arr[largest]:
largest := left

// Check if right child is larger than the largest so far


if right < n and arr[right] > arr[largest]:
largest := right

// If the largest is not the root, swap them and recursively heapify the affected sub-tree
if largest != i:
swap(arr[i], arr[largest])
heapify(arr, n, largest)

Algorithm:-
procedure heapSort(arr):
n := length(arr)

// Build Max Heap


for i from n / 2 - 1 down to 0:
heapify(arr, n, i)

// Sorting phase
for i from n - 1 down to 1:
// Swap the root (maximum element) with the last element
swap(arr[0], arr[i])

// Heapify the reduced heap


heapify(arr, i, 0)

procedure heapify(arr, n, i):


largest := i
left := 2 * i + 1
right := 2 * i + 2
// Compare with left child
if left < n and arr[left] > arr[largest]:
largest := left

// Compare with right child


if right < n and arr[right] > arr[largest]:
largest := right

// If the largest is not the root, swap and recursively heapify the affected sub-tree
if largest != i:
swap(arr[i], arr[largest])
heapify(arr, n, largest)

Program:-
// Heap Sort in C

#include <stdio.h>

// Function to swap the position of two elements

void swap(int* a, int* b)


{

int temp = *a;


*a = *b;
*b = temp;
}

// To heapify a subtree rooted with node i


// which is an index in arr[].
// n is size of heap
void heapify(int arr[], int N, int i)
{
// Find largest among root,
// left child and right child

// Initialize largest as root


int largest = i;

// left = 2*i + 1
int left = 2 * i + 1;

// right = 2*i + 2
int right = 2 * i + 2;

// If left child is larger than root


if (left < N && arr[left] > arr[largest])

largest = left;

// If right child is larger than largest


// so far
if (right < N && arr[right] > arr[largest])

largest = right;

// Swap and continue heapifying


// if root is not largest
// If largest is not root
if (largest != i) {

swap(&arr[i], &arr[largest]);

// Recursively heapify the affected


// sub-tree
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);
}
}

// A utility function to print array of size n


void printArray(int arr[], int N)
{
for (int i = 0; i < N; i++)
printf("%d ", arr[i]);
printf("\n");
}

// Driver's code
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int N = sizeof(arr) / sizeof(arr[0]);

// Function call
heapSort(arr, N);
printf("Sorted array is\n");
printArray(arr, N);
}

Objective 2:- Implementation and anaylsis of Counting Sort

Pseudocode:-

procedure countingSort(arr):
// Find the maximum value in the input array
maxVal := findMax(arr)

// Create an array to store the count of each element


count := new Array[maxVal + 1]

// Initialize the count array with zeros


for i from 0 to maxVal:
count[i] := 0

// Count the occurrences of each element in the input array


for i from 0 to length(arr) - 1:
count[arr[i]] := count[arr[i]] + 1

// Update the count array to store the actual position of each element in the sorted array
for i from 1 to maxVal:
count[i] := count[i] + count[i - 1]

// Create a temporary array to store the sorted result


output := new Array[length(arr)]

// Build the sorted array by placing elements in their correct positions


for i from length(arr) - 1 down to 0:
output[count[arr[i]] - 1] := arr[i]
count[arr[i]] := count[arr[i]] - 1
// Copy the sorted array back to the original array
for i from 0 to length(arr) - 1:
arr[i] := output[i]

// Helper function to find the maximum value in an array


function findMax(arr):
maxVal := arr[0]
for i from 1 to length(arr) - 1:
if arr[i] > maxVal:
maxVal := arr[i]
return maxVal

Algorithm:-
countingSort(arr, n)
maximum <- find the largest element in arr
create a count array of size maximum+1
initialise count array with all 0's
for i <- 0 to n
find the total frequency/ occurrences of each element and
store the count at ith index in count arr

for i <- 1 to maximum


find the cumulative sum by adding current(i) and prev(i-1) count and store
it in count arr itself

for j <- n down to 1


copy the element back into the input array
decrement count of each element copied by 1

Program:-

#include <stdio.h>

void countingSort(int arr[], int n) {


int arr1[10];

int x = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > x)
x = arr[i];
}

int count_arr[10];

for (int i = 0; i <= x; ++i) {


count_arr[i] = 0;
}

for (int i = 0; i < n; i++) {


count_arr[arr[i]]++;
}

for (int i = 1; i <= x; i++) {


count_arr[i] += count_arr[i - 1];
}

for (int i = n - 1; i >= 0; i--) {


arr1[count_arr[arr[i]] - 1] = arr[i];
count_arr[arr[i]]--;
}

for (int i = 0; i < n; i++) {


arr[i] = arr1[i];
}
}

void display(int arr[], int n) {


for (int i = 0; i < n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {4, 2, 2, 8, 3, 3, 1};
int n = sizeof(arr) / sizeof(arr[0]);
countingSort(arr, n);
display(arr, n);
}
Experiment No. :- 5

Objective 1:- Implementation and analysis of Radix Sort

Pseudocode:-

Radix-Sort(A, d)
for j = 1 to d do
int count[10] = {0};
for i = 0 to n do
count[key of(A[i]) in pass j]++
for k = 1 to 10 do
count[k] = count[k] + count[k-1]
for i = n-1 downto 0 do
result[ count[key of(A[i])] ] = A[j]
count[key of(A[i])]--
for i=0 to n do
A[i] = result[i]
end for(j)
end func
Algorithm:-
radixSort(arr)
max = largest element in the given array
d = number of digits in the largest element (or, max)
Now, create d buckets of size 0 - 9
for i -> 0 to d
sort the array elements using counting sort (or any stable sort) according to the digits at
the ith place
Program:-

#include<stdio.h>
#include<stdlib.h>
int *Radix_sort(int *arr, int size);
int *Count_sort(int *arr, int size, int Exponent);
int maximum(int *arr,int length);
int minimum(int *arr,int length);
int main()
{
int i, size;
int *arr;
printf("Enter the array size: ");
scanf("%d",&size);
arr = (int *) malloc( sizeof( int ) * size );
if(arr==NULL)
{
exit(-1);//abnormal termination.
}
else
{
// Entering the array values
printf("Enter the array\n");
for(i = 0; i < size; i++)
{
printf("arr[ %d ] = ",i);
scanf("%d",&arr[i]);
}
printf("Array before sorting:\n");
for(i = 0; i < size; i++)
{
printf("arr[%d] = %d\n",i,arr[i]);
}

arr = Radix_sort(arr,size);
}
printf("ARRAY AFTER SORTING: \n");
for(int i=0;i<size;i++)
{
printf("arr[ %d ] = %d \n",i ,arr[i]);
}
}

int *Radix_sort(int *arr, int size)


{
int Max_of_arr = maximum(arr, size);
int Exponent = 1;
int count = 0;
while(Exponent <= Max_of_arr)
{
arr = Count_sort(arr, size, Exponent);
Exponent= Exponent* 10;
//uncomment the loop to see how sorting happens digit after moving from LSB to MSB.
/*
printf("ARRAY AFTER SORTING: %d digits from rightmost element\n",count);
for(int i=0;i<size;i++)
printf("arr[ %d ] = %d \n",i ,arr[i]);
count++;
*/
}
return arr;
}

int *Count_sort(int *arr, int size, int Exponent)


{
int range = 10;
int *frequency_array ;
frequency_array = (int*)malloc(sizeof(int)* range);
if(frequency_array == NULL)
{
exit(-1);
}
int sum=0;
for(int i=0; i<range; i++)
{
frequency_array[ i ]=0;
}

for(int i=0;i<size;i++)
{
frequency_array[ (arr[i]/Exponent)%10 ]++;
}

for(int i =0; i<range;i++)


{
sum = sum + frequency_array[i];
frequency_array[i] = sum;
}

int *new_arr;//new array to store the result.


new_arr = (int *)malloc(sizeof(int) *size);
if(new_arr == NULL)
{
exit(-1);
}
else
{
int pos;
for(int i=size-1; i>=0 ;i-- )
{
pos = frequency_array[(arr[i]/Exponent)%10]-1;
new_arr[ pos ] = arr[ i ];
frequency_array [(arr[i]/Exponent)%10]--;
}
}
return new_arr;
}
int maximum(int *arr, int length)
{
int max=INT_MIN;
for( int i=0 ; i<length ; i++ )
{
if(arr[i]>max)
max=arr[i];
}
return max;
}
int minimum(int *arr, int length)
{
int min=INT_MAX;
for( int i=0 ; i<length ; i++ )
{
if(arr[i]<min)
min=arr[i];
}
return min;
}
Objective 2:- Implementation of Shell Sort

Pseudocode:-
procedure shellSort(arr):
n := length(arr)

// Start with a large gap and reduce it until it becomes 1


gap := n / 2
while gap > 0:
// Perform gapped insertion sort for the current gap
for i from gap to n - 1:
// Add arr[i] to the elements that have been gap sorted
temp := arr[i]

// Shift earlier gap-sorted elements until the correct position for arr[i] is found
j := i
while j >= gap and arr[j - gap] > temp:
arr[j] := arr[j - gap]
j := j - gap

// Place temp (the original arr[i]) in its correct position


arr[j] := temp

// Reduce the gap for the next iteration


gap := gap / 2
Algorithm:-
procedure shellSort(arr):
n := length(arr)

// Start with a large gap and reduce it until it becomes 1


gap := n / 2
while gap > 0:
// Perform gapped insertion sort for the current gap
for i from gap to n - 1:
// Add arr[i] to the elements that have been gap-sorted
temp := arr[i]

// Shift earlier gap-sorted elements until the correct position for arr[i] is found
j := i
while j >= gap and arr[j - gap] > temp:
arr[j] := arr[j - gap]
j := j - gap

// Place temp (the original arr[i]) in its correct position


arr[j] := temp

// Reduce the gap for the next iteration


gap := gap / 2
Program:-
// Shell Sort in C programming

#include <stdio.h>

// Shell sort
void shellSort(int array[], int n) {
// Rearrange elements at each n/2, n/4, n/8, ... intervals
for (int interval = n / 2; interval > 0; interval /= 2) {
for (int i = interval; i < n; i += 1) {
int temp = array[i];
int j;
for (j = i; j >= interval && array[j - interval] > temp; j -= interval) {
array[j] = array[j - interval];
}
array[j] = temp;
}
}
}

// Print an array
void printArray(int array[], int size) {
for (int i = 0; i < size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}

// Driver code
int main() {
int data[] = {9, 8, 3, 7, 5, 6, 4, 1};
int size = sizeof(data) / sizeof(data[0]);
shellSort(data, size);
printf("Sorted array: \n");
printArray(data, size);
}
Experiment No. :- 6

Objective 1:- Implementation of Activity Selection Problem

Pseudocode:-
procedure activitySelection(start, finish):
// Assuming activities are already sorted by their finish times

n := length(start)
// The first activity is always selected
selectedActivities := [0]

// Index of the last selected activity


lastSelected := 0

// Iterate through the rest of the activities


for i from 1 to n - 1:
// If this activity has a start time greater than or equal to the finish time
// of the previously selected activity, add it to the selected activities
if start[i] >= finish[lastSelected]:
selectedActivities.append(i)
lastSelected := i

return selectedActivities

Algorithm:-
procedure activitySelection(start, finish):
// Assuming activities are already sorted by their finish times

n := length(start)

// The first activity is always selected


selectedActivities := [0]

// Index of the last selected activity


lastSelected := 0

// Iterate through the rest of the activities


for i from 1 to n - 1:
// If this activity has a start time greater than or equal to the finish time
// of the previously selected activity, add it to the selected activities
if start[i] >= finish[lastSelected]:
selectedActivities.append(i)
lastSelected := i

return selectedActivities
Program:-
#include <stdio.h>

// Structure to represent an activity


struct Activity {
int start;
int finish;
};

// Function to perform activity selection


void activitySelection(struct Activity activities[], int n) {
// Assuming activities are already sorted by their finish times

printf("Selected activities:\n");

// The first activity is always selected


int i = 0;
printf("(%d, %d) ", activities[i].start, activities[i].finish);

// Iterate through the rest of the activities


for (int j = 1; j < n; j++) {
// If this activity has a start time greater than or equal to the finish time
// of the previously selected activity, add it to the selected activities
if (activities[j].start >= activities[i].finish) {
printf("(%d, %d) ", activities[j].start, activities[j].finish);
i = j;
}
}
}

int main() {
// Example activities array
struct Activity activities[] = {
{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}
};

int n = sizeof(activities) / sizeof(activities[0]);

// Assuming activities are sorted by finish times


activitySelection(activities, n);

return 0;
}

Objective 2:- Implementation of Knapsack Problem using Greedy Solution.

Pseudocode:-
procedure fractionalKnapsack(values, weights, capacity):
n := length(values)

// Calculate the value-to-weight ratios for each item


ratios := new Array[n]
for i from 0 to n - 1:
ratios[i] := values[i] / weights[i]

// Sort items based on value-to-weight ratio in descending order


sortItemsByRatio(values, weights, ratios, n)

// Initialize variables
totalValue := 0.0
remainingCapacity := capacity

// Iterate through the sorted items


for i from 0 to n - 1:
// Take as much of the current item as possible
amountTaken := min(remainingCapacity, weights[i])
// Update variables
totalValue := totalValue + amountTaken * ratios[i]
remainingCapacity := remainingCapacity - amountTaken

// If the knapsack is full, break


if remainingCapacity == 0:
break

return totalValue

// Helper function to sort items based on value-to-weight ratio


procedure sortItemsByRatio(values, weights, ratios, n):
for i from 0 to n - 1:
for j from i + 1 to n - 1:
// Sort in descending order based on ratio
if ratios[i] < ratios[j]:
swap(values[i], values[j])
swap(weights[i], weights[j])
swap(ratios[i], ratios[j])

Algorithm:-
procedure fractionalKnapsack(values, weights, capacity):
n := length(values)

// Calculate the value-to-weight ratios for each item


ratios := new Array[n]
for i from 0 to n - 1:
ratios[i] := values[i] / weights[i]

// Sort items based on value-to-weight ratio in descending order


sortItemsByRatio(values, weights, ratios, n)

// Initialize variables
totalValue := 0.0
remainingCapacity := capacity

// Iterate through the sorted items


for i from 0 to n - 1:
// Take as much of the current item as possible
amountTaken := min(remainingCapacity, weights[i])

// Update variables
totalValue := totalValue + amountTaken * ratios[i]
remainingCapacity := remainingCapacity - amountTaken

// If the knapsack is full, break


if remainingCapacity == 0:
break

return totalValue

// Helper function to sort items based on value-to-weight ratio


procedure sortItemsByRatio(values, weights, ratios, n):
for i from 0 to n - 1:
for j from i + 1 to n - 1:
// Sort in descending order based on ratio
if ratios[i] < ratios[j]:
swap(values[i], values[j])
swap(weights[i], weights[j])
swap(ratios[i], ratios[j])

Program:-
#include <stdio.h>
#include <stdlib.h>

// Structure to represent an item


struct Item {
int value;
int weight;
};

// Function to compare items based on their value-to-weight ratio


int compare(const void *a, const void *b) {
double ratioA = ((double)(((struct Item*)a)->value) / ((struct Item*)a)->weight);
double ratioB = ((double)(((struct Item*)b)->value) / ((struct Item*)b)->weight);
if (ratioA > ratioB)
return -1;
else if (ratioA < ratioB)
return 1;
else
return 0;
}

// Function to solve the Fractional Knapsack Problem using a greedy approach


double fractionalKnapsack(struct Item items[], int n, int capacity) {
// Sort items based on their value-to-weight ratio in descending order
qsort(items, n, sizeof(struct Item), compare);

double totalValue = 0.0;


int currentWeight = 0;

// Iterate through sorted items and add them to the knapsack


for (int i = 0; i < n; i++) {
if (currentWeight + items[i].weight <= capacity) {
// Take the whole item if it fits
totalValue += items[i].value;
currentWeight += items[i].weight;
} else {
// Take a fraction of the item if it doesn't fit completely
double remainingWeight = capacity - currentWeight;
totalValue += (remainingWeight / items[i].weight) * items[i].value;
break; // Knapsack is full
}
}

return totalValue;
}

int main() {
// Example items array
struct Item items[] = {
{60, 10}, {100, 20}, {120, 30}
};
int n = sizeof(items) / sizeof(items[0]);
int capacity = 50;

double result = fractionalKnapsack(items, n, capacity);

printf("Maximum value in Knapsack = %.2lf\n", result);

return 0;
}
Experiment No. :-7
Objective 1:- Implementation and analysis of the 0/1 Knapsack problem using dynamic programming
method
Pseudocode:-
function knapsack(weights[1..n], values[1..n], capacity)
// Create a table to store the maximum values for subproblems
let dp[0..n][0..capacity] be a 2D array

// Initialize the base cases


for w from 0 to capacity:
dp[0][w] = 0
for i from 0 to n:
dp[i][0] = 0

// Build the table using bottom-up dynamic programming


for i from 1 to n:
for w from 1 to capacity:
if weights[i] <= w:
dp[i][w] = max(values[i] + dp[i-1][w-weights[i]], dp[i-1][w])
else:
dp[i][w] = dp[i-1][w]

// The maximum value is stored in dp[n][capacity]

// Backtrack to find the selected items


let selected_items be an empty set
i = n, w = capacity
while i > 0 and w > 0:
if dp[i][w] != dp[i-1][w]:
// Item i was included in the optimal solution
selected_items.add(i)
w = w - weights[i]
i=i-1

return dp[n][capacity], selected_items


Algorithm:-

Dynamic-0-1-knapsack (v, w, n, W)

for w = 0 to W do

c[0, w] = 0

for i = 1 to n do

c[i, 0] = 0

for w = 1 to W do

if wi ≤ w then

if vi + c[i-1, w-wi] then

c[i, w] = vi + c[i-1, w-wi]

else c[i, w] = c[i-1, w]


else

c[i, w] = c[i-1, w]
Program:-

/* A Naive recursive implementation


of 0-1 Knapsack problem */
#include <stdio.h>

// A utility function that returns


// maximum of two integers
int max(int a, int b) { return (a > b) ? a : b; }

// Returns the maximum value that can be


// put in a knapsack of capacity W
int knapSack(int W, int wt[], int val[], int n)
{
// Base Case
if (n == 0 || W == 0)
return 0;

// If weight of the nth item is more than


// Knapsack capacity W, then this item cannot
// be included in the optimal solution
if (wt[n - 1] > W)
return knapSack(W, wt, val, n - 1);

// Return the maximum of two cases:


// (1) nth item included
// (2) not included
else
return max(
val[n - 1]
+ knapSack(W - wt[n - 1], wt, val, n - 1),
knapSack(W, wt, val, n - 1));
}

// Driver code
int main()
{
int profit[] = { 60, 100, 120 };
int weight[] = { 10, 20, 30 };
int W = 50;
int n = sizeof(profit) / sizeof(profit[0]);
printf("%d", knapSack(W, weight, profit, n));
return 0;
}

Objective 2:- Implementation and Analysis of LCS


Pseudocode:-
function lcs(X[1..m], Y[1..n])
// Create a table to store the lengths of LCS for subproblems
let dp[0..m][0..n] be a 2D array

// Initialize the base cases


for i from 0 to m:
dp[i][0] = 0
for j from 0 to n:
dp[0][j] = 0

// Build the table using bottom-up dynamic programming


for i from 1 to m:
for j from 1 to n:
if X[i] == Y[j]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
// The length of the LCS is stored in dp[m][n]
let length = dp[m][n]

// Reconstruct the LCS


let lcs_sequence[length] be an array
i = m, j = n, index = length-1
while i > 0 and j > 0:
if X[i] == Y[j]:
lcs_sequence[index] = X[i]
i=i-1
j=j-1
index = index - 1
else if dp[i-1][j] > dp[i][j-1]:
i=i-1
else:
j=j-1

// The LCS sequence is stored in lcs_sequence

return length, lcs_sequence

Algorithm:-

Input: Two sequences, X of length m and Y of length n.

Initialize: Create a 2D array dp of size (m+1) x (n+1) to store the lengths of LCS.

Initialize the first row and first column of dp with zeros.

Dynamic Programming: Iterate over each character in X and Y using two nested loops.

If X[i] is equal to Y[j], set dp[i+1][j+1] = dp[i][j] + 1.

If X[i] is not equal to Y[j], set dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]).

Backtracking (Optional): Starting from the bottom-right corner of the dp array, backtrack to reconstruct the
LCS.

If X[i] == Y[j], include X[i] (or Y[j]) in the LCS, move diagonally up and left in the dp array.

If X[i] != Y[j], move in the direction of the larger value (either up or left).
Output: The length of the LCS is dp[m][n].

Optionally, the LCS itself can be reconstructed using the backtracking information.

Program:-
// The longest common subsequence in C

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

int i, j, m, n, LCS_table[20][20];
char S1[20] = "ACADB", S2[20] = "CBDA", b[20][20];

void lcsAlgo() {
m = strlen(S1);
n = strlen(S2);

// Filling 0's in the matrix


for (i = 0; i <= m; i++)
LCS_table[i][0] = 0;
for (i = 0; i <= n; i++)
LCS_table[0][i] = 0;

// Building the mtrix in bottom-up way


for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++) {
if (S1[i - 1] == S2[j - 1]) {
LCS_table[i][j] = LCS_table[i - 1][j - 1] + 1;
} else if (LCS_table[i - 1][j] >= LCS_table[i][j - 1]) {
LCS_table[i][j] = LCS_table[i - 1][j];
} else {
LCS_table[i][j] = LCS_table[i][j - 1];
}
}

int index = LCS_table[m][n];


char lcsAlgo[index + 1];
lcsAlgo[index] = '\0';
int i = m, j = n;
while (i > 0 && j > 0) {
if (S1[i - 1] == S2[j - 1]) {
lcsAlgo[index - 1] = S1[i - 1];
i--;
j--;
index--;
}

else if (LCS_table[i - 1][j] > LCS_table[i][j - 1])


i--;
else
j--;
}

// Printing the sub sequences


printf("S1 : %s \nS2 : %s \n", S1, S2);
printf("LCS: %s", lcsAlgo);
}

int main() {
lcsAlgo();
printf("\n");
}
Experiment No. :-8

Objective 1:- Implementation of Kruskal’s algorithm to find MST.


Pseudocode:-
KruskalMST(G):
DisjointSets forest
foreach (Vertex v : G):
forest.makeSet(v)
PriorityQueue Q // min edge weight
foreach (Edge e : G):
Q.insert(e)
Graph T = (V, {})
while |T.edges()| < n-1:
Vertex (u, v) = Q.removeMin()
if forest.find(u) != forest.find(v):
T.addEdge(u, v)
forest.union( forest.find(u),
forest.find(v) )
return T
Algorithm:-
Kruskal's Algorithm:

1. Input: A connected, undirected graph G with vertices V and edges E.

2. Output: The minimum spanning tree of G.

3. Procedure Kruskal(G):

4. Sort all the edges of G in non-decreasing order of their weights.

5. Initialize an empty set MST to represent the minimum spanning tree.

6. Create an empty priority queue or list to store the edges sorted by weight.

7. Create an array parent[V] to keep track of the parent of each vertex (initially each vertex is its own parent).

8. for each vertex v in V:

9. parent[v] = v // Each vertex is initially its own parent.

10. for each edge (u, v) in sorted order of edges:

11. if FindSet(u) is not equal to FindSet(v): // Check if adding the edge forms a cycle.

12. Add (u, v) to MST.

13. Union(u, v) // Merge the sets of u and v.

14. return MST

15. Function FindSet(v):

16. if parent[v] is not equal to v:

17. parent[v] = FindSet(parent[v])

18. return parent[v]

19. Function Union(u, v):

20. rootU = FindSet(u)

21. rootV = FindSet(v)


22. parent[rootU] = rootV

Program:-

// Kruskal's algorithm in C

#include <stdio.h>

#define MAX 30

typedef struct edge {

int u, v, w;

} edge;

typedef struct edge_list {

edge data[MAX];

int n;

} edge_list;

edge_list elist;

int Graph[MAX][MAX], n;

edge_list spanlist;

void kruskalAlgo();

int find(int belongs[], int vertexno);


void applyUnion(int belongs[], int c1, int c2);

void sort();

void print();

// Applying Krushkal Algo

void kruskalAlgo() {

int belongs[MAX], i, j, cno1, cno2;

elist.n = 0;

for (i = 1; i < n; i++)

for (j = 0; j < i; j++) {

if (Graph[i][j] != 0) {

elist.data[elist.n].u = i;

elist.data[elist.n].v = j;

elist.data[elist.n].w = Graph[i][j];

elist.n++;

sort();

for (i = 0; i < n; i++)

belongs[i] = i;
spanlist.n = 0;

for (i = 0; i < elist.n; i++) {

cno1 = find(belongs, elist.data[i].u);

cno2 = find(belongs, elist.data[i].v);

if (cno1 != cno2) {

spanlist.data[spanlist.n] = elist.data[i];

spanlist.n = spanlist.n + 1;

applyUnion(belongs, cno1, cno2);

int find(int belongs[], int vertexno) {

return (belongs[vertexno]);

void applyUnion(int belongs[], int c1, int c2) {

int i;

for (i = 0; i < n; i++)

if (belongs[i] == c2)

belongs[i] = c1;
}

// Sorting algo

void sort() {

int i, j;

edge temp;

for (i = 1; i < elist.n; i++)

for (j = 0; j < elist.n - 1; j++)

if (elist.data[j].w > elist.data[j + 1].w) {

temp = elist.data[j];

elist.data[j] = elist.data[j + 1];

elist.data[j + 1] = temp;

// Printing the result

void print() {

int i, cost = 0;

for (i = 0; i < spanlist.n; i++) {

printf("\n%d - %d : %d", spanlist.data[i].u, spanlist.data[i].v, spanlist.data[i].w);

cost = cost + spanlist.data[i].w;

}
printf("\nSpanning tree cost: %d", cost);

int main() {

int i, j, total_cost;

n = 6;

Graph[0][0] = 0;

Graph[0][1] = 4;

Graph[0][2] = 4;

Graph[0][3] = 0;

Graph[0][4] = 0;

Graph[0][5] = 0;

Graph[0][6] = 0;

Graph[1][0] = 4;

Graph[1][1] = 0;

Graph[1][2] = 2;

Graph[1][3] = 0;

Graph[1][4] = 0;

Graph[1][5] = 0;

Graph[1][6] = 0;
Graph[2][0] = 4;

Graph[2][1] = 2;

Graph[2][2] = 0;

Graph[2][3] = 3;

Graph[2][4] = 4;

Graph[2][5] = 0;

Graph[2][6] = 0;

Graph[3][0] = 0;

Graph[3][1] = 0;

Graph[3][2] = 3;

Graph[3][3] = 0;

Graph[3][4] = 3;

Graph[3][5] = 0;

Graph[3][6] = 0;

Graph[4][0] = 0;

Graph[4][1] = 0;

Graph[4][2] = 4;

Graph[4][3] = 3;

Graph[4][4] = 0;

Graph[4][5] = 0;

Graph[4][6] = 0;
Graph[5][0] = 0;

Graph[5][1] = 0;

Graph[5][2] = 2;

Graph[5][3] = 0;

Graph[5][4] = 3;

Graph[5][5] = 0;

Graph[5][6] = 0;

kruskalAlgo();

print();

Objective 2:- Implementation of Prim’s Algorithm to find MST.


Pseudocode:-
Prim's Algorithm (graph, start):
Initialize key[] array with a large value for all vertices
Set key[start] to 0
Create a set MSTSet to keep track of vertices included in MST
Repeat until all vertices are included in MST:
1. u = Extract the minimum key vertex from the set of vertices not yet included in MST
2. Include u in MSTSet
3. Update the key values of all adjacent vertices of u if they are smaller than the current key values

Return MSTSet
Algorithm:-
Create a set MSTSet to keep track of vertices included in the Minimum Spanning Tree (MST).

Initialize key[] array with a large value for all vertices and set key[start] to 0, where start is the starting vertex.

Repeat the following steps until all vertices are included in the MST:

a. Pick the minimum key vertex u from the set of vertices not yet included in MST.

b. Include u in MSTSet.

c. Update the key values of all adjacent vertices of u if they are smaller than the current key values.

The final MST is formed by MSTSet.


Program:-

#include <stdio.h>
#include <limits.h>

#define V 5 // Number of vertices in the graph

int minKey(int key[], int mstSet[]) {


int min = INT_MAX, min_index;

for (int v = 0; v < V; v++) {


if (mstSet[v] == 0 && key[v] < min) {
min = key[v];
min_index = v;
}
}

return min_index;
}

void printMST(int parent[], int graph[V][V]) {


printf("Edge \tWeight\n");
for (int i = 1; i < V; i++)
printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]);
}

void primMST(int graph[V][V]) {


int parent[V]; // Array to store constructed MST
int key[V]; // Key values used to pick minimum weight edge in cut
int mstSet[V]; // To represent set of vertices not yet included in MST

// Initialize all keys as INFINITE


// and mstSet[] as false
for (int i = 0; i < V; i++) {
key[i] = INT_MAX;
mstSet[i] = 0;
}

// Always include the first vertex in MST.


// Make the key 0 so that this vertex is picked as the first vertex.
key[0] = 0;
parent[0] = -1; // First node is always root of MST

// The MST will have V vertices


for (int count = 0; count < V - 1; count++) {
// Pick the minimum key vertex from the
// set of vertices not yet included in MST
int u = minKey(key, mstSet);

// Add the picked vertex to the MST Set


mstSet[u] = 1;

// Update key value and parent index of


// the adjacent vertices of the picked vertex.
// Consider only those vertices which are not
// yet included in the MST
for (int v = 0; v < V; v++) {
// graph[u][v] is non-zero only for adjacent vertices of m
// mstSet[v] is false for vertices not yet included in MST
// Update the key only if the graph[u][v] is smaller than key[v]
if (graph[u][v] && mstSet[v] == 0 && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}

// Print the constructed MST


printMST(parent, graph);
}

// Driver program to test above function


int main() {
// Sample graph
int graph[V][V] = {
{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0}
};

// Print the MST using Prim's algorithm


primMST(graph);

return 0;
}
Experiment No. :- 9

Objective 1:- Implementation of Warshal’s Algorithm for all pair shortest path.
Pseudocode:-
procedure Warshall(graph):
V <- number of vertices in graph
dist[][] <- copy of graph[][]

for k from 0 to V-1:


for i from 0 to V-1:
for j from 0 to V-1:
if dist[i][k] + dist[k][j] < dist[i][j]:
dist[i][j] <- dist[i][k] + dist[k][j]

print the final dist[][]


Algorithm:-
Input: Adjacency matrix graph[V][V] where V is the number of vertices.
Initialize the distance matrix dist[][] with the same values as the adjacency matrix.
Loop over all vertices k from 0 to V-1:
a. Loop over all pairs of vertices i and j from 0 to V-1:
- If dist[i][k] + dist[k][j] < dist[i][j], update dist[i][j] with the new minimum value.
The final dist[][] matrix contains the shortest path distances between all pairs of vertices.
Program:-

// C Program for Floyd Warshall Algorithm

#include <stdio.h>

// Number of vertices in the graph

#define V 4

/* Define Infinite as a large enough

value. This value will be used

for vertices not connected to each other */

#define INF 99999

// A function to print the solution matrix

void printSolution(int dist[][V]);

// Solves the all-pairs shortest path

// problem using Floyd Warshall algorithm

void floydWarshall(int dist[][V])

int i, j, k;

/* Add all vertices one by one to


the set of intermediate vertices.

---> Before start of an iteration, we

have shortest distances between all

pairs of vertices such that the shortest

distances consider only the

vertices in set {0, 1, 2, .. k-1} as

intermediate vertices.

----> After the end of an iteration,

vertex no. k is added to the set of

intermediate vertices and the set

becomes {0, 1, 2, .. k} */

for (k = 0; k < V; k++) {

// Pick all vertices as source one by one

for (i = 0; i < V; i++) {

// Pick all vertices as destination for the

// above picked source

for (j = 0; j < V; j++) {

// If vertex k is on the shortest path from

// i to j, then update the value of

// dist[i][j]

if (dist[i][k] + dist[k][j] < dist[i][j])

dist[i][j] = dist[i][k] + dist[k][j];

}
}

// Print the shortest distance matrix

printSolution(dist);

/* A utility function to print solution */

void printSolution(int dist[][V])

printf(

"The following matrix shows the shortest distances"

" between every pair of vertices \n");

for (int i = 0; i < V; i++) {

for (int j = 0; j < V; j++) {

if (dist[i][j] == INF)

printf("%7s", "INF");

else

printf("%7d", dist[i][j]);

printf("\n");

// driver's code

int main()

/* Let us create the following weighted graph


10

(0)------->(3)

| /|\

5| |

| |1

\|/ |

(1)------->(2)

3 */

int graph[V][V] = { { 0, 5, INF, 10 },

{ INF, 0, 3, INF },

{ INF, INF, 0, 1 },

{ INF, INF, INF, 0 } };

// Function call

floydWarshall(graph);

return 0;

Objective 2:- Implementation of Dijkstra’s Algorithm for single source shortest path.
Pseudocode:-
function Dijkstra(graph, source):

create a set to store vertices

create an array to store distances

create a boolean array to track processed vertices

initialize distances to INFINITE

set distance for the source vertex to 0

repeat until all vertices are processed:

u = vertex with the minimum distance value in the set

mark u as processed

for each neighbor v of u:

if v is not processed and the new distance to v through u is smaller:

update distance to v

return the array of distances

Algorithm:-
Create a set to store vertices, distances, and a boolean array to track if a vertex is included in the shortest path
tree.
Initialize all distances as INFINITE and set the source vertex distance to 0.
Repeat the following until all vertices are included in the shortest path tree:
a. Pick the minimum distance vertex from the set of vertices not yet processed.
b. Update the distance values of the adjacent vertices of the picked vertex.
c. Mark the picked vertex as processed.
The array containing the shortest distances from the source vertex represents the shortest path from the source
to all other vertices.
Program:-
#include <stdio.h>
#include <limits.h>

#define V 6 // Number of vertices in the graph


int minDistance(int dist[], int sptSet[]) {
int min = INT_MAX, min_index;

for (int v = 0; v < V; v++)


if (sptSet[v] == 0 && dist[v] <= min)
min = dist[v], min_index = v;

return min_index;
}

void printSolution(int dist[]) {


printf("Vertex \t Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t %d\n", i, dist[i]);
}

void dijkstra(int graph[V][V], int src) {


int dist[V]; // The output array dist[i] holds the shortest distance from src to i.
int sptSet[V]; // sptSet[i] is true if vertex i is included in the shortest path tree or the shortest distance from
src to i is finalized.

for (int i = 0; i < V; i++)


dist[i] = INT_MAX, sptSet[i] = 0;

dist[src] = 0;

for (int count = 0; count < V - 1; count++) {


int u = minDistance(dist, sptSet);
sptSet[u] = 1;

for (int v = 0; v < V; v++)


if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}

printSolution(dist);
}
int main() {
int graph[V][V] = {
{0, 1, 4, 0, 0, 0},
{1, 0, 4, 2, 7, 0},
{4, 4, 0, 3, 5, 0},
{0, 2, 3, 0, 4, 6},
{0, 7, 5, 4, 0, 7},
{0, 0, 0, 6, 7, 0}
};

dijkstra(graph, 0);

return 0;
}
Experiment No. :-10

Objective 1:- Implementation of N-Queen Problem using Backtracking


Pseudocode:-
function solveNQueens(board, col):

if col >= N:

return true // All queens are placed successfully

for each row in board:

if isSafe(board, row, col):

placeQueen(board, row, col) // Place queen in this cell

if solveNQueens(board, col + 1):

return true // If placing queen in this cell leads to a solution

removeQueen(board, row, col) // Remove queen if it doesn't lead to a solution

return false // If no row worked, trigger backtracking

function isSafe(board, row, col):

// Check if no queen can attack in this row, column, or diagonals

// Returns true if it's safe, false otherwise


function placeQueen(board, row, col):

// Mark the cell as occupied by a queen

function removeQueen(board, row, col):

// Unmark the cell, backtrack by removing the queen

Algorithm:-
Start in the leftmost column.
If all queens are placed, return true.
Try all rows in the current column. For each row, do the following:
a. If the queen can be placed safely in this row and column, mark this cell and recursively try to place the queen
in the next column.
b. If placing the queen in the current cell leads to a solution, return true.
c. If placing the queen in the current cell does not lead to a solution, unmark this cell (backtrack) and try the
next row.
If all rows have been tried and none worked, return false to trigger backtracking.
Program:-
#include <stdio.h>
#include <stdbool.h>

#define N 8 // Change N to the desired size of the chessboard

void printSolution(int board[N][N]) {


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
printf("%2d ", board[i][j]);
printf("\n");
}
}

bool isSafe(int board[N][N], int row, int col) {


// Check for queens in the same row
for (int i = 0; i < col; i++)
if (board[row][i])
return false;

// Check upper diagonal on left side


for (int i = row, j = col; i >= 0 && j >= 0; i--, j--)
if (board[i][j])
return false;

// Check lower diagonal on left side


for (int i = row, j = col; i < N && j >= 0; i++, j--)
if (board[i][j])
return false;

return true;
}

bool solveNQueensUtil(int board[N][N], int col) {


if (col >= N)
return true;

for (int i = 0; i < N; i++) {


if (isSafe(board, i, col)) {
board[i][col] = 1;

if (solveNQueensUtil(board, col + 1))


return true;

board[i][col] = 0; // Backtrack
}
}

return false;
}

bool solveNQueens() {
int board[N][N] = {0};

if (!solveNQueensUtil(board, 0)) {
printf("Solution does not exist");
return false;
}
printSolution(board);
return true;
}

int main() {
solveNQueens();
return 0;
}

Objective 2:- Implementation of Sum Subset Problem using Backtracking


Pseudocode:-
function displaySubset()
Print "Subset: { "
for i from 0 to n-1
if subset[i] is 1
Print i+1, " "
Print "}\n"

function subsetSum(s, k, r)
subset[k] = 1
if s+k is equal to sum
displaySubset()
else if s+k+subset[k+1] is less than or equal to sum
subsetSum(s+k, k+1, r-k)

if s+r-k is greater than or equal to sum and s+subset[k+1] is less than or equal to sum
subset[k] = 0
subsetSum(s, k+1, r-k)

function solveSubsetSum()
total = 0
for i from 1 to n
total += i

if total is less than sum or 1 is greater than sum


Print "No solution"
return

Print "Solutions:"
subsetSum(0, 1, total)

function main()
Input n
Input sum
solveSubsetSum()
return 0
Algorithm:-
Input the number of elements n and the desired sum sum from the user.
Calculate the total sum of all elements from 1 to n.
Check if there is any possibility of obtaining the desired sum. If not, print "No solution" and exit.
Initialize the subset array and call the subsetSum function with appropriate parameters.
The subsetSum function uses backtracking to explore all possible subsets that sum to the desired sum.
If a subset is found, display it.
Continue exploring subsets until all possibilities are exhausted.

Program:-
#include <stdio.h>

#define MAX 100

int subset[MAX];
int n, sum;

void displaySubset() {
printf("Subset: { ");
for (int i = 0; i < n; i++) {
if (subset[i] == 1) {
printf("%d ", i + 1);
}
}
printf("}\n");
}

void subsetSum(int s, int k, int r) {


subset[k] = 1;
if (s + k == sum) {
displaySubset();
} else if (s + k + subset[k + 1] <= sum) {
subsetSum(s + k, k + 1, r - k);
}

if ((s + r - k >= sum) && (s + subset[k + 1] <= sum)) {


subset[k] = 0;
subsetSum(s, k + 1, r - k);
}
}

void solveSubsetSum() {
int total = 0;
for (int i = 1; i <= n; i++) {
total += i;
}

if (total < sum || 1 > sum) {


printf("No solution\n");
return;
}

printf("Solutions:\n");
subsetSum(0, 1, total);
}
int main() {
printf("Enter the number of elements: ");
scanf("%d", &n);

printf("Enter the desired sum: ");


scanf("%d", &sum);

solveSubsetSum();

return 0;
}
Experiment No. :-11

Objective 1:- Implementation of Naïve String matching algorithm


Pseudocode:-
procedure NaiveStringMatch(text, pattern)
n = length(text)
m = length(pattern)

for i = 0 to n - m
j=0
while j < m and text[i + j] = pattern[j]
j=j+1
end while

if j = m
print "Pattern found at index", i
end if
end for
end procedure
Algorithm:-

Read the text and pattern as input.

Initialize variables n and m as the lengths of the text and pattern, respectively.

Iterate from i = 0 to n - m:

Initialize a variable j to 0.

Inside the loop, compare characters of the text and pattern:

If text[i + j] != pattern[j], break the loop.

Increment j.
If j becomes equal to m, print the index i as the pattern is found starting at that index.
Program:-

// C program for Naive Pattern Searching algorithm

#include <stdio.h>

#include <string.h>

void search(char* pat, char* txt)

int M = strlen(pat);

int N = strlen(txt);

/* A loop to slide pat[] one by one */

for (int i = 0; i <= N - M; i++) {

int j;

/* For current index i, check for pattern match */

for (j = 0; j < M; j++)

if (txt[i + j] != pat[j])

break;

if (j

== M) // if pat[0...M-1] = txt[i, i+1, ...i+M-1]

printf("Pattern found at index %d \n", i);

// Driver's code

int main()
{

char txt[] = "AABAACAADAABAAABAA";

char pat[] = "AABA";

// Function call

search(pat, txt);

return 0;

Objective 2:- Implementation of Rabin Karp String Matching Algorithm


Pseudocode:-
function RabinKarpSearch(text, pattern):
n = length of text
m = length of pattern
d = a prime number (chosen based on the character set)
q = a prime number (chosen as a large prime)

// Calculate d^(m-1) % q
h = d^(m-1) % q

// Calculate hash values for the pattern and the initial substring in the text
patternHash = calculateHash(pattern, m, d, q)
textHash = calculateHash(text[0:m], m, d, q)
// Iterate through the text
for i from 0 to n-m:
// Check if the hash values match
if patternHash = textHash:
// Check character by character if it's a match
if text[i:i+m] equals pattern:
print "Pattern found at index", i

Algorithm:-
Preprocess the pattern to calculate its hash value.
Slide the pattern over the text one character at a time and recalculate the hash value of the current substring.
If the hash values match, compare each character of the pattern with the corresponding characters in the
substring to confirm the match.
Program:-

/* Following program is a C implementation of Rabin Karp

Algorithm given in the CLRS book */

#include <stdio.h>

#include <string.h>

// d is the number of characters in the input alphabet

#define d 256

/* pat -> pattern

txt -> text

q -> A prime number

*/

void search(char pat[], char txt[], int q)

int M = strlen(pat);

int N = strlen(txt);

int i, j;
int p = 0; // hash value for pattern

int t = 0; // hash value for txt

int h = 1;

// The value of h would be "pow(d, M-1)%q"

for (i = 0; i < M - 1; i++)

h = (h * d) % q;

// Calculate the hash value of pattern and first

// window of text

for (i = 0; i < M; i++) {

p = (d * p + pat[i]) % q;

t = (d * t + txt[i]) % q;

// Slide the pattern over text one by one

for (i = 0; i <= N - M; i++) {

// Check the hash values of current window of text

// and pattern. If the hash values match then only

// check for characters one by one

if (p == t) {

/* Check for characters one by one */

for (j = 0; j < M; j++) {

if (txt[i + j] != pat[j])

break;

// if p == t and pat[0...M-1] = txt[i, i+1,


// ...i+M-1]

if (j == M)

printf("Pattern found at index %d \n", i);

// Calculate hash value for next window of text:

// Remove leading digit, add trailing digit

if (i < N - M) {

t = (d * (t - txt[i] * h) + txt[i + M]) % q;

// We might get negative value of t, converting

// it to positive

if (t < 0)

t = (t + q);

/* Driver Code */

int main()

char txt[] = "GEEKS FOR GEEKS";

char pat[] = "GEEK";

// A prime number

int q = 101;

// function call
search(pat, txt, q);

return 0;

}
Experiment No. :-12

Objective:- Implementation to find all Hamiltonian cycle in a connected undirected graph.

Pseudocode:-
function hamiltonianCycle(graph):

path = array of size V

for i from 0 to V-1:

path[i] = -1

path[0] = 0

if hamiltonianCycleUtil(graph, path, 1) is false:

print "Solution does not exist"

else:

printSolution(path)

function hamiltonianCycleUtil(graph, path, pos):

if pos is equal to V:

if there is an edge from path[pos - 1] to path[0]:

return true

else:

return false

for v from 1 to V-1:

if isSafe(v, graph, path, pos):

path[pos] = v
if hamiltonianCycleUtil(graph, path, pos + 1) is true:

return true

path[pos] = -1 // Backtrack

return false

function isSafe(v, graph, path, pos):

if graph[path[pos - 1]][v] is 0:

return false

for i from 0 to pos-1:

if path[i] is equal to v:

return false

return true

function printSolution(path):

print "Hamiltonian Cycle exists:"

for i from 0 to V-1:

print path[i]

print path[0] // Complete the cycle

Algorithm:-
Initialize the path array to store the Hamiltonian cycle.
Start from the first vertex and set it as the starting point in the path array.
Use backtracking to try all possible vertices for the next position in the path array.
Check if the chosen vertex is adjacent to the last added vertex and has not been included before.
If a Hamiltonian cycle is found, print the solution.
Program:-
#include <stdio.h>
#include <stdbool.h>

#define V 5 // Adjust the number of vertices as needed


void printSolution(int path[]);
bool isSafe(int v, bool graph[V][V], int path[], int pos);
bool hamiltonianCycleUtil(bool graph[V][V], int path[], int pos);

void hamiltonianCycle(bool graph[V][V]) {


int path[V];
for (int i = 0; i < V; i++)
path[i] = -1;

path[0] = 0; // Start from the first vertex

if (hamiltonianCycleUtil(graph, path, 1) == false) {


printf("Solution does not exist\n");
return;
}

printSolution(path);
}

bool hamiltonianCycleUtil(bool graph[V][V], int path[], int pos) {


if (pos == V) {
// Check if there is an edge from the last vertex to the first vertex
if (graph[path[pos - 1]][path[0]] == 1)
return true;
else
return false;
}

for (int v = 1; v < V; v++) {


if (isSafe(v, graph, path, pos)) {
path[pos] = v;

if (hamiltonianCycleUtil(graph, path, pos + 1) == true)


return true;

path[pos] = -1; // Backtrack


}
}
return false;
}

bool isSafe(int v, bool graph[V][V], int path[], int pos) {


// Check if this vertex is an adjacent vertex of the previously added vertex
if (graph[path[pos - 1]][v] == 0)
return false;

// Check if the vertex has not already been included


for (int i = 0; i < pos; i++)
if (path[i] == v)
return false;

return true;
}

void printSolution(int path[]) {


printf("Hamiltonian Cycle exists: \n");
for (int i = 0; i < V; i++)
printf("%d ", path[i]);
printf("%d ", path[0]); // Complete the cycle
printf("\n");
}

int main() {
bool graph[V][V] = {
{0, 1, 1, 1, 0},
{1, 0, 1, 0, 1},
{1, 1, 0, 1, 1},
{1, 0, 1, 0, 0},
{0, 1, 1, 0, 0}
};

hamiltonianCycle(graph);

return 0;
}
Experiment No. :-13
Objective:- Implementation of Insertion operation in RB Tree
Pseudocode:-
RB-INSERT(T, z):

// Standard BST Insertion

y = NIL

x = T.root

while x != NIL:

y=x

if z.key < x.key:

x = x.left

else:

x = x.right

z.parent = y

if y == NIL:

T.root = z

else if z.key < y.key:

y.left = z

else:

y.right = z

// Color the new node as RED

z.color = RED

// Fix violations

RB-INSERT-FIXUP(T, z)

RB-INSERT-FIXUP(T, z):
while z.parent.color == RED:

if z.parent == z.parent.parent.left:

y = z.parent.parent.right

if y.color == RED:

// Case 1: Recolor

z.parent.color = BLACK

y.color = BLACK

z.parent.parent.color = RED

z = z.parent.parent

else:

if z == z.parent.right:

// Case 2: Left-Right rotation

z = z.parent

LEFT-ROTATE(T, z)

// Case 3: Right rotation

z.parent.color = BLACK

z.parent.parent.color = RED

RIGHT-ROTATE(T, z.parent.parent)

else:

// Symmetric case

//

// Ensure the root is BLACK

T.root.color = BLACK

Algorithm:-
Insertion:Perform a standard binary search tree insertion.

Color the new node as RED.

Fix Violations: If the parent of the newly inserted node is BLACK, the tree remains valid, and no further action
is needed.

If the parent is RED, there may be a violation of the Red-Black Tree properties.

Recolor or Restructure: Check the color of the uncle (sibling of the parent of the new node).

If the uncle is RED, recolor the parent and uncle to BLACK and the grandparent to RED. Then, continue the
fix-up process on the grandparent.

If the uncle is BLACK or NULL: If the new node and its parent are in a zig-zag configuration, perform a
rotation (left-right or right-left) to make them in a line.

After rotation, recolor the original parent to BLACK, the original grandparent to RED, and perform another
rotation.

If the new node and its parent are in a line configuration, perform a rotation to balance the tree.

Recolor the original parent to BLACK and the original grandparent to RED.

Root Adjustment: After the fix-up process, the root of the tree may change. Ensure that the root is always
BLACK

Program:-
#include <stdio.h>
#include <stdlib.h>
struct node {
int d;
int c;
struct node* p;
struct node* r;
struct node* l;
};
struct node* root = NULL;
struct node* bst(struct node* trav,
struct node* temp)
{
if (trav == NULL)
return temp;
if (temp->d < trav->d)
{
trav->l = bst(trav->l, temp);
trav->l->p = trav;
}
else if (temp->d > trav->d)
{
trav->r = bst(trav->r, temp);
trav->r->p = trav;
}
return trav;
}
void rightrotate(struct node* temp)
{
struct node* left = temp->l;
temp->l = left->r;
if (temp->l)
temp->l->p = temp;
left->p = temp->p;
if (!temp->p)
root = left;
else if (temp == temp->p->l)
temp->p->l = left;
else
temp->p->r = left;
left->r = temp;
temp->p = left;
}

// Function performing left rotation


// of the passed node
void leftrotate(struct node* temp)
{
struct node* right = temp->r;
temp->r = right->l;
if (temp->r)
temp->r->p = temp;
right->p = temp->p;
if (!temp->p)
root = right;
else if (temp == temp->p->l)
temp->p->l = right;
else
temp->p->r = right;
right->l = temp;
temp->p = right;
}
void fixup(struct node* root, struct node* pt)
{
struct node* parent_pt = NULL;
struct node* grand_parent_pt = NULL;

while ((pt != root) && (pt->c != 0)


&& (pt->p->c == 1))
{
parent_pt = pt->p;
grand_parent_pt = pt->p->p;
if (parent_pt == grand_parent_pt->l)
{

struct node* uncle_pt = grand_parent_pt->r;


if (uncle_pt != NULL && uncle_pt->c == 1)
{
grand_parent_pt->c = 1;
parent_pt->c = 0;
uncle_pt->c = 0;
pt = grand_parent_pt;
}

else {
if (pt == parent_pt->r) {
leftrotate(parent_pt);
pt = parent_pt;
parent_pt = pt->p;
}
rightrotate(grand_parent_pt);
int t = parent_pt->c;
parent_pt->c = grand_parent_pt->c;
grand_parent_pt->c = t;
pt = parent_pt;
}
}
else {
struct node* uncle_pt = grand_parent_pt->l;
if ((uncle_pt != NULL) && (uncle_pt->c == 1))
{
grand_parent_pt->c = 1;
parent_pt->c = 0;
uncle_pt->c = 0;
pt = grand_parent_pt;
}
else {
if (pt == parent_pt->l) {
rightrotate(parent_pt);
pt = parent_pt;
parent_pt = pt->p;
}

/* Case : 3
pt is right child of its parent
Left-rotation required */
leftrotate(grand_parent_pt);
int t = parent_pt->c;
parent_pt->c = grand_parent_pt->c;
grand_parent_pt->c = t;
pt = parent_pt;
}
}
}
}
void inorder(struct node* trav)
{
if (trav == NULL)
return;
inorder(trav->l);
printf("%d ", trav->d);
inorder(trav->r);
}
int main()
{
int n = 7;
int a[7] = { 7, 6, 5, 4, 3, 2, 1 };
for (int i = 0; i < n; i++) {
struct node* temp
= (struct node*)malloc(sizeof(struct node));
temp->r = NULL;
temp->l = NULL;
temp->p = NULL;
temp->d = a[i];
temp->c = 1;
root = bst(root, temp);
fixup(root, temp);
root->c = 0;
}
printf("Inorder Traversal of Created Tree\n");
inorder(root);
return 0;
}
Experiment No. :-14

Objective:- Implementation of Insertion operation of B-Tree


Pseudocode:-
function BTreeInsert(root, key):
if root is NULL:
// Tree is empty, create a new root
root = createNode()
root.keys[0] = key
root.numKeys = 1
else:
newNode = NULL
newKey = insertNonFull(root, key, &newNode)
if newKey != -1:
// Root split occurred, create a new root
newRoot = createNode()
newRoot.keys[0] = newKey
newRoot.children[0] = root
newRoot.children[1] = newNode
newRoot.numKeys = 1
root = newRoot
function insertNonFull(node, key, child):
index = node.numKeys - 1
if node.isLeaf:
// Node is a leaf, insert the key
while index >= 0 and key < node.keys[index]:
node.keys[index + 1] = node.keys[index]
index--
node.keys[index + 1] = key
node.numKeys++
return -1 // No split occurred
else:
// Node is not a leaf, find the child to insert into
while index >= 0 and key < node.keys[index]:
index--
index++
result = insertNonFull(node.children[index], key, &newChild)
if result == -1:
// No split occurred
return -1
else:
key = result
index = node.numKeys - 1
// Insert the new key into the current node
while index >= 0 and key < node.keys[index]:
node.keys[index + 1] = node.keys[index]
node.children[index + 2] = node.children[index + 1]
index--
node.keys[index + 1] = key
node.children[index + 2] = newChild
node.numKeys++
if node.numKeys > MAX_KEYS:
// Split occurred
*child = splitNode(node)
return node.keys[node.numKeys / 2]
else:
return -1
function splitNode(node):
middleIndex = node.numKeys / 2
newNode = createNode()
newNode.isLeaf = node.isLeaf
newNode.numKeys = MAX_KEYS - middleIndex - 1
for i = 0 to newNode.numKeys - 1:
newNode.keys[i] = node.keys[middleIndex + 1 + i]
newNode.children[i] = node.children[middleIndex + 1 + i]
newNode.children[newNode.numKeys] = node.children[node.numKeys]
node.numKeys = middleIndex
return newNode
Algorithm:-
Start at the root of the tree.
If the root is full, split it.
Traverse down the tree to find the appropriate leaf node for insertion.
If the leaf node is not full, insert the key.
If the leaf node is full, split it.
Propagate the split information up the tree if necessary.
If the root is split, create a new root.
Program:-
#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;
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;
}
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++;
}
void splitNode(int val, int *pval, int pos, struct BTreeNode *node,
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--;
}
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--)
;
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;
}
void insert(int val) {
int flag, i;
struct BTreeNode *child;

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


if (flag)
root = createNode(i, child);
}
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;
}
}
search(val, pos, myNode->link[*pos]);

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

You might also like