1. A.
Implement Binary Search Tree and Perform the following operations
i. Insert
ii. Search
iii. Delete
iv. In-order
B. Write a program to implement merge sort for the following array.
Array: ["apple", "banana", "grape", "cherry", "date"]
A. Implement Binary Search Tree and Perform the following operations
#include <stdio.h>
#include <stdlib.h>
struct Node {
int key;
struct Node *left, *right;
};
// Create a new 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;
// In-order traversal
void inorder(struct Node* root) {
if (root != NULL) {
inorder(root->left);
printf("%d ", root->key);
inorder(root->right);
// Insert a node
struct Node* insert(struct Node* node, int key) {
if (node == NULL) return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
return node;
// Search for a node
struct Node* search(struct Node* root, int key) {
if (root == NULL || root->key == key)
return root;
if (key < root->key)
return search(root->left, key);
return search(root->right, key);
}
// Find the in-order successor
struct Node* minValueNode(struct Node* node) {
struct Node* current = node;
while (current && current->left != NULL)
current = current->left;
return current;
// Delete a node
struct Node* deleteNode(struct Node* root, int key) {
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) {
struct Node* temp = root->right;
free(root);
return temp;
} else if (root->right == NULL) {
struct Node* temp = root->left;
free(root);
return temp;
struct Node* temp = minValueNode(root->right);
root->key = temp->key;
root->right = deleteNode(root->right, temp->key);
return root;
int main() {
struct Node* root = NULL;
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 70);
root = insert(root, 60);
root = insert(root, 80);
printf("In-order traversal: ");
inorder(root);
printf("\n");
int key = 40;
if (search(root, key) != NULL)
printf("Node %d found in the tree.\n", key);
else
printf("Node %d not found in the tree.\n", key);
root = deleteNode(root, 20);
printf("In-order traversal after deleting 20: ");
inorder(root);
printf("\n");
return 0;
[Link] a program to implement merge sort for the following array.
Array: ["apple", "banana", "grape", "cherry", "date"]
#include <stdio.h>
#include <string.h>
void merge(char arr[][20], int l, int m, int r) {
int n1 = m - l + 1;
int n2 = r - m;
char L[n1][20], R[n2][20];
for (int i = 0; i < n1; i++)
strcpy(L[i], arr[l + i]);
for (int j = 0; j < n2; j++)
strcpy(R[j], arr[m + 1 + j]);
int i = 0, j = 0, k = l;
while (i < n1 && j < n2) {
if (strcmp(L[i], R[j]) <= 0) {
strcpy(arr[k], L[i]);
i++;
} else {
strcpy(arr[k], R[j]);
j++;
k++;
while (i < n1) {
strcpy(arr[k], L[i]);
i++;
k++;
while (j < n2) {
strcpy(arr[k], R[j]);
j++;
k++;
void mergeSort(char arr[][20], int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
int main() {
char arr[5][20] = {"apple", "banana", "grape", "cherry", "date"};
int arr_size = 5;
printf("Given array: ");
for (int i = 0; i < arr_size; i++)
printf("%s ", arr[i]);
printf("\n");
mergeSort(arr, 0, arr_size - 1);
printf("Sorted array: ");
for (int i = 0; i < arr_size; i++)
printf("%s ", arr[i]);
printf("\n");
return 0;
}
2 A. Write a Program to implement Quick Sort for Sorting an Array of Structures
for given input.
Array of Structures:
1. Name: "Alice", Score: 50
2. Name: "Bob", Score: 80
3. Name: "Charlie", Score: 70
4. Name: "David", Score: 90
B. Write a program to implement the Towers of Hanoi problem using recursion.
A. Write a Program to implement Quick Sort for Sorting an Array of Structures for
given input.
Array of Structures:
1. Name: "Alice", Score: 50
2. Name: "Bob", Score: 80
3. Name: "Charlie", Score: 70
4. Name: "David", Score: 90
#include <stdio.h>
#include <string.h>
struct Student {
char name[20];
int score;
};
void swap(struct Student* a, struct Student* b) {
struct Student temp = *a;
*a = *b;
*b = temp;
}
int partition(struct Student arr[], int low, int high) {
int pivot = arr[high].score;
int i = (low - 1);
for (int j = low; j < high; j++) {
if (arr[j].score < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
void quickSort(struct Student arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
int main() {
struct Student arr[] = {{"Alice", 50}, {"Bob", 80}, {"Charlie", 70}, {"David", 90}};
int n = sizeof(arr) / sizeof(arr[0]);
quickSort(arr, 0, n - 1);
printf("Sorted array of structures by score:\n");
for (int i = 0; i < n; i++) {
printf("Name: %s, Score: %d\n", arr[i].name, arr[i].score);
}
return 0;
}
[Link] a program to implement the Towers of Hanoi problem using recursion.
#include <stdio.h>
void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod) {
if (n == 1) {
printf("Move disk 1 from rod %c to rod %c\n", from_rod, to_rod);
return;
towerOfHanoi(n - 1, from_rod, aux_rod, to_rod);
printf("Move disk %d from rod %c to rod %c\n", n, from_rod, to_rod);
towerOfHanoi(n - 1, aux_rod, to_rod, from_rod);
int main() {
int n = 3; // Number of disks
towerOfHanoi(n, 'A', 'C', 'B'); // A, B, and C are names of rods
return 0;
}
3. A. Write a program to solve the Fractional Knapsack Problem for multiple test
cases.
Number of test cases: 2
Test case 1:
Number of items: 3
Items (Value, Weight): [(60, 10), (100, 20), (120, 30)]
Knapsack capacity: 50
Test case 2:
Number of items: 4
Items (Value, Weight): [(60, 10), (40, 40), (100, 20), (120, 30)]
Knapsack capacity: 50
B. Write a program to implement Dijkstra’s Algorithm to find the shortest path
from a source vertex to all other vertices in a weighted, directed graph.
Number of vertices: 5
Graph (Adjacency Matrix):
0 10 0 0 20
10 0 10 0 0
0 10 0 30 0
0 0 30 0 0
20 0 0 0 0
Source vertex: 0
A. Write a program to solve the Fractional Knapsack Problem for multiple test cases.
Number of test cases: 2
Test case 1:
Number of items: 3
Items (Value, Weight): [(60, 10), (100, 20), (120, 30)]
Knapsack capacity: 50
Test case 2:
Number of items: 4
Items (Value, Weight): [(60, 10), (40, 40), (100, 20), (120, 30)]
Knapsack capacity: 50
#include <stdio.h>
#include <stdlib.h>
struct Item {
int value;
int weight;
};
int compare(const void* a, const void* b) {
double r1 = ((struct Item*)a)->value / (double)((struct Item*)a)->weight;
double r2 = ((struct Item*)b)->value / (double)((struct Item*)b)->weight;
return (r1 < r2) ? 1 : -1;
}
double fractionalKnapsack(struct Item arr[], int n, int capacity) {
qsort(arr, n, sizeof(struct Item), compare);
double totalValue = 0.0;
for (int i = 0; i < n; i++) {
if (arr[i].weight <= capacity) {
capacity -= arr[i].weight;
totalValue += arr[i].value;
} else {
totalValue += arr[i].value * ((double)capacity / arr[i].weight);
break;
}
}
return totalValue;
}
int main() {
struct Item items1[] = {{60, 10}, {100, 20}, {120, 30}};
int capacity1 = 50;
int n1 = sizeof(items1) / sizeof(items1[0]);
printf("Test Case 1 - Maximum value in Knapsack = %.2f\n",
fractionalKnapsack(items1, n1, capacity1));
struct Item items2[] = {{60, 10}, {40, 40}, {100, 20}, {120, 30}};
int capacity2 = 50;
int n2 = sizeof(items2) / sizeof(items2[0]);
printf("Test Case 2 - Maximum value in Knapsack = %.2f\n",
fractionalKnapsack(items2, n2, capacity2));
return 0;
}
B. Write a program to implement Dijkstra’s Algorithm to find the shortest path from a
source vertex to all other vertices in a weighted, directed graph.
Number of vertices: 5
Graph (Adjacency Matrix):
0 10 0 0 20
10 0 10 0 0
0 10 0 30 0
0 0 30 0 0
20 0 0 0 0
Source vertex: 0
#include <stdio.h>
#include <limits.h>
#define V 5
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 dijkstra(int graph[V][V], int src) {
int dist[V];
int sptSet[V];
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];
}
printf("Vertex \t\t Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t\t %d\n", i, dist[i]);
}
int main() {
int graph[V][V] = {
{0, 10, 0, 0, 20},
{10, 0, 10, 0, 0},
{0, 10, 0, 30, 0},
{0, 0, 30, 0, 0},
{20, 0, 0, 0, 0}
};
int src = 0;
dijkstra(graph, src);
return 0;
}
4. A. Write a program to verify whether the given graph is connected before finding
the Minimum Spanning Tree using Prim’s Algorithm or Kruskal’s Algorithm.
Number of vertices: 4
Graph (Adjacency Matrix):
0100
1010
0101
0010
B. Write a program to implement Huffman Coding for a given set of characters
and their frequencies.
Character and frequency pairs:
A: 5, B: 9, C: 12, D: 13, E: 16, F: 45
A. Write a program to verify whether the given graph is connected before finding the
Minimum Spanning Tree using Prim’s Algorithm or Kruskal’s Algorithm.
Number of vertices: 4
Graph (Adjacency Matrix):
0100
1010
0101
0010
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#define V 4
void DFS(int graph[V][V], bool visited[], int v) {
visited[v] = true;
for (int i = 0; i < V; i++)
if (graph[v][i] && !visited[i])
DFS(graph, visited, i);
}
bool isConnected(int graph[V][V]) {
bool visited[V] = {false};
DFS(graph, visited, 0);
for (int i = 0; i < V; i++)
if (!visited[i])
return false;
return true;
}
int minKey(int key[], bool mstSet[]) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (mstSet[v] == false && key[v] < min)
min = key[v], min_index = v;
return min_index;
}
void primMST(int graph[V][V]) {
int parent[V];
int key[V];
bool mstSet[V];
for (int i = 0; i < V; i++)
key[i] = INT_MAX, mstSet[i] = false;
key[0] = 0;
parent[0] = -1;
for (int count = 0; count < V - 1; count++) {
int u = minKey(key, mstSet);
mstSet[u] = true;
for (int v = 0; v < V; v++)
if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v])
parent[v] = u, key[v] = graph[u][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]]);
}
int main() {
int graph[V][V] = {
{0, 1, 0, 0},
{1, 0, 1, 0},
{0, 1, 0, 1},
{0, 0, 1, 0}
};
if (isConnected(graph)) {
printf("The graph is connected.\n");
printf("Minimum Spanning Tree using Prim's Algorithm:\n");
primMST(graph);
} else {
printf("The graph is not connected. MST cannot be found.\n");
}
return 0;
}
[Link] a program to implement Huffman Coding for a given set of characters and
their frequencies.
Character and frequency pairs:
A: 5, B: 9, C: 12, D: 13, E: 16, F: 45
#include <stdio.h>
#include <stdlib.h>
#define MAX_TREE_HT 100
struct MinHeapNode {
char data;
unsigned freq;
struct MinHeapNode *left, *right;
};
struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHeapNode** array;
};
struct MinHeapNode* newNode(char data, unsigned freq) {
struct MinHeapNode* temp = (struct MinHeapNode*)malloc(sizeof(struct
MinHeapNode));
temp->left = temp->right = NULL;
temp->data = data;
temp->freq = freq;
return temp;
}
struct MinHeap* createMinHeap(unsigned capacity) {
struct MinHeap* minHeap = (struct MinHeap*)malloc(sizeof(struct
MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (struct MinHeapNode**)malloc(minHeap->capacity *
sizeof(struct MinHeapNode*));
return minHeap;
}
void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) {
struct MinHeapNode* t = *a;
*a = *b;
*b = t;
}
void minHeapify(struct MinHeap* minHeap, int idx) {
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < minHeap->size && minHeap->array[left]->freq < minHeap-
>array[smallest]->freq)
smallest = left;
if (right < minHeap->size && minHeap->array[right]->freq < minHeap-
>array[smallest]->freq)
smallest = right;
if (smallest != idx) {
swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
int isSizeOne(struct MinHeap* minHeap) {
return (minHeap->size == 1);
}
struct MinHeapNode* extractMin(struct MinHeap* minHeap) {
struct MinHeapNode* temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode*
minHeapNode) {
++minHeap->size;
int i = minHeap->size - 1;
while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
minHeap->array[i] = minHeapNode;
}
void printArr(int arr[], int n) {
for (int i = 0; i < n; ++i)
printf("%d", arr[i]);
printf("\n");
}
int isLeaf(struct MinHeapNode* root) {
return !(root->left) && !(root->right);
}
struct MinHeap* createAndBuildMinHeap(char data[], int freq[], int size) {
struct MinHeap* minHeap = createMinHeap(size);
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(data[i], freq[i]);
minHeap->size = size;
for (int i = (minHeap->size - 2) / 2; i >= 0; --i)
minHeapify(minHeap, i);
return minHeap;
}
struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) {
struct MinHeapNode *left, *right, *top;
struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size);
while (!isSizeOne(minHeap)) {
left = extractMin(minHeap);
right = extractMin(minHeap);
top = newNode('$', left->freq + right->freq);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
void printCodes(struct MinHeapNode* root, int arr[], int top) {
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1);
}
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1);
}
if (isLeaf(root)) {
printf("%c: ", root->data);
printArr(arr, top);
}
}
void HuffmanCodes(char data[], int freq[], int size) {
struct MinHeapNode* root = buildHuffmanTree(data, freq, size);
int arr[MAX_TREE_HT], top = 0;
printCodes(root, arr, top);
}
int main() {
char arr[] = {'A', 'B', 'C', 'D', 'E', 'F'};
int freq[] = {5, 9, 12, 13, 16, 45};
int size = sizeof(arr) / sizeof(arr[0]);
printf("Huffman Codes:\n");
HuffmanCodes(arr, freq, size);
return 0;
}
5. A. Find the Transitive closure of a given directed graph using Warshall’s
algorithm.
B. Write a Program to Implement Floyds Algorithm.
A. Find the Transitive closure of a given directed graph using Warshall’s algorithm.
#include <stdio.h>
#define V 4
void warshall(int graph[V][V]) {
for (int k = 0; k < V; k++)
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
graph[i][j] = graph[i][j] || (graph[i][k] && graph[k][j]);
void printMatrix(int graph[V][V]) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++)
printf("%d ", graph[i][j]);
printf("\n");
int main() {
int graph[V][V] = {
{0, 1, 0, 1},
{0, 0, 1, 0},
{1, 0, 0, 1},
{0, 0, 0, 0}
};
printf("Original adjacency matrix:\n");
printMatrix(graph);
warshall(graph);
printf("\nTransitive closure matrix:\n");
printMatrix(graph);
return 0;
B. Write a Program to Implement Floyds Algorithm.
#include <stdio.h>
#define V 4
#define INF 99999
void floydWarshall(int graph[V][V]) {
int dist[V][V];
for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
dist[i][j] = graph[i][j];
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
printf("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");
}
}
int main() {
int graph[V][V] = {
{0, 15, INF, 7},
{5, 0, 50, INF},
{INF, 30, 0, 5},
{INF, INF, 15, 0}
};
floydWarshall(graph);
return 0;
}
[Link] a program to solve multiple instances of the 0/1 Knapsack problem using the
Dynamic Programming approach.
Test case 1:
Number of items: 4
Item Weights: [1, 3, 4, 5]
Item Values: [1, 4, 5, 7]
Knapsack Capacity: 7
Test case 2:
Number of items: 3
Item Weights: [2, 3, 4]
Item Values: [3, 4, 5]
Knapsack Capacity: 5
#include <stdio.h>
int knapsack(int weights[], int values[], int n, int capacity) {
int dp[n + 1][capacity + 1];
// Build the dp table
for (int i = 0; i <= n; i++) {
for (int w = 0; w <= capacity; w++) {
if (i == 0 || w == 0)
dp[i][w] = 0;
else if (weights[i - 1] <= w)
dp[i][w] = (values[i - 1] + dp[i - 1][w - weights[i - 1]] > dp[i - 1][w]) ?
values[i - 1] + dp[i - 1][w - weights[i - 1]] : dp[i - 1][w];
else
dp[i][w] = dp[i - 1][w];
}
}
// Return the maximum value in the bottom-right cell of the table
return dp[n][capacity];
}
int main() {
// Test Case 1
int weights1[] = {1, 3, 4, 5};
int values1[] = {1, 4, 5, 7};
int capacity1 = 7;
int n1 = sizeof(weights1) / sizeof(weights1[0]);
// Test Case 2
int weights2[] = {2, 3, 4};
int values2[] = {3, 4, 5};
int capacity2 = 5;
int n2 = sizeof(weights2) / sizeof(weights2[0]);
printf("Test Case 1:\n");
printf("Maximum value in Knapsack = %d\n", knapsack(weights1,
values1, n1, capacity1));
printf("Test Case 2:\n");
printf("Maximum value in Knapsack = %d\n", knapsack(weights2,
values2, n2, capacity2));
return 0;
}
[Link] all the nodes reachable from a given starting node “B” in a given Undirected
graph using BFS, DFS method.
#include <stdio.h>
#include <stdlib.h>
#define MAX_NODES 100
int graph[MAX_NODES][MAX_NODES];
int visited[MAX_NODES];
int n;
void initializeVisited() {
for (int i = 0; i < n; i++) {
visited[i] = 0;
void BFS(int start) {
int queue[MAX_NODES], front = 0, rear = 0;
visited[start] = 1;
queue[rear++] = start;
printf("BFS: ");
while (front < rear) {
int current = queue[front++];
printf("%c ", current + 'A');
for (int i = 0; i < n; i++) {
if (graph[current][i] == 1 && !visited[i]) {
visited[i] = 1;
queue[rear++] = i;
printf("\n");
void DFS(int start) {
printf("%c ", start + 'A');
visited[start] = 1;
for (int i = 0; i < n; i++) {
if (graph[start][i] == 1 && !visited[i]) {
DFS(i);
int main() {
n = 5;
graph[0][1] = graph[1][0] = 1;
graph[0][4] = graph[4][0] = 1;
graph[1][2] = graph[2][1] = 1;
graph[1][3] = graph[3][1] = 1;
graph[1][4] = graph[4][1] = 1;
graph[3][4] = graph[4][3] = 1;
initializeVisited();
BFS(1);
printf("DFS: ");
initializeVisited();
DFS(1);
printf("\n");
return 0;