DS Practical
DS Practical
Set A.
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node *left,*right;
};
switch(choice){
case 1:
printf("Enter value to insert:");
scanf("%d",&value);
root=insert(root,value);
break;
case 2:
printf("Enter value to search:");
scanf("%d",&value);
if(search(root,value))
printf("Value found in BST.\n");
else
printf("Value not found.\n");
break;
case 3:
printf("Inorder Traversal:");
inorder(root);
printf("\n");
break;
case 4:
printf("Preorder Traversal:");
inorder(root);
printf("\n");
break;
case 5:
printf("Preorder Traversal:");
inorder(root);
printf("\n");
break;
case 6:
printf("Exiting program.\n");
return 0;
default:
}
}
return 0;
}
Set B.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left,*right;
};
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
struct Node* insert(struct Node* root, int data) {
if (root == NULL)
return createNode(data);
if (data < root->data)
root->left = insert(root->left, data);
else if (data > root->data)
root->right = insert(root->right, data);
return root;
}
struct Node* copy(struct Node* root) {
if (root == NULL) return NULL;
Node* newRoot = createNode(root->data);
newRoot->left = copy(root->left);
newRoot->right = copy(root->right);
return newRoot;
}
int compare(Node* root1, Node* root2) {
if (root1 == NULL && root2 == NULL) return 1;
if (root1 == NULL || root2 == NULL) return 0;
return (root1->data == root2->data) && compare(root1->left, root2->left) && compare(root1-
>right,root2->right);
}
void inorder(struct Node* root) {
if (root == NULL) return;
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
void freeTree(Node* root) {
if (root == NULL) return;
freeTree(root->left);
freeTree(root->right);
free(root);
}
int main() {
Node* root = NULL;
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 70);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 60);
root = insert(root, 80);
inorder(root);
printf("\n");
if (compare(root, copyRoot))
printf("BSTs are identical.\n");
else
printf("BSTs are not identical.\n");
freeTree(root);
freeTree(copyRoot);
return 0;
}
Set C.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int key;
return temp;
}
struct Node* insert(struct Node* node, int key) {
else
return node;
}
node = node->left;
return node;
}
if (root->left == NULL) {
free(root);
return temp;
return temp;
root->key = temp->key;
}
return root;
if (root != NULL) {
inorder(root->left);
inorder(root->right);
}
}
int main() {
inorder(root);
printf("\n");
printf("\n");
return 0;
}
Assignment 2
Set A.
#include <stdio.h>
#include <stdlib.h>
int data;
struct Node*treeNode;
};
if (!newNode) {
printf("Memory error\n");
return NULL;
}
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
if (root == NULL) {
return createNode(data);
}
if (data < root->data)
root->left = insert(root->left, data);
else
return root;
}
return q;
newNode->next = NULL;
if (q->rear) {
q->rear->next = newNode;
q->rear = newNode;
if (!q->front) {
q->front = newNode;
if (!q->front) {
return NULL;
}
struct QueueNode *temp = q->front;
struct Node *treeNode = temp->treeNode;
q->front = q->front->next;
if (!q->front) {
q->rear = NULL;
free(temp);
return treeNode;
}
if (!root) return;
int level = 0;
while (!isQueueEmpty(q)) {
int nodeCount = 0;
while (!isQueueEmpty(q)) {
nodeCount++;
q = tempQ;
level++;
}
free(q);
int main() {
printLevels(root);
return 0;
}
Set B.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
*b = temp;
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
largest = right;
if (largest != i) {
swap(&arr[i], &arr[largest]);
heapify(arr, n, largest);
}
heapify(arr, n, i);
swap(&arr[0], &arr[i]);
heapify(arr, i, 0);
}
}
void printArray(int arr[], int n) {
printf("\n");
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
srand(time(0));
printf("\n");
heapSort(arr, n);
return 0;
}
Set C.
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode* next;
};
struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
};
struct ListNode* findMiddle(struct ListNode* start, struct ListNode* end) {
struct ListNode *slow = start, *fast = start;
while (fast != end && fast->next != end) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
struct TreeNode* sortedListToBST(struct ListNode* start, struct ListNode* end) {
if (start == end) return NULL;
struct ListNode* mid = findMiddle(start, end);
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->data = mid->data;
root->left = sortedListToBST(start, mid);
root->right = sortedListToBST(mid->next, end);
return root;
}
struct ListNode* newListNode(int data) {
struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->data = data;
node->next = NULL;
return node;
}
void inorderTraversal(struct TreeNode* root) {
if (!root) return;
inorderTraversal(root->left);
printf("%d ", root->data);
inorderTraversal(root->right);
}
int main() {
struct ListNode* head = newListNode(-10);
head->next = newListNode(-3);
head->next->next = newListNode(0);
head->next->next->next = newListNode(5);
head->next->next->next->next = newListNode(9);
struct TreeNode* root = sortedListToBST(head, NULL);
printf("Inorder Traversal of BST: ");
inorderTraversal(root);
return 0;
}
Assignment 3.
Set A.
#include <stdio.h>
adj[i][j] = 0;
adj[dest][src] = 1;
}
}
printf("\nAdjacency Matrix:\n");
printf("\n");
int main() {
scanf("%d", &edges);
displayAdjMatrix(adj, vertices);
return 0;
}
Set B .
#include <stdio.h>
#include <stdlib.h>
int adjMatrix[MAX][MAX];
int visited[MAX];
adjMatrix[i][j] = 0;
visited[i] = 0;
adjMatrix[u][v] = 1;
adjMatrix[v][u] = 1;
printf("\nAdjacency Matrix:\n");
printf("\n");
visited[node] = 1;
for (int i = 0; i < vertices; i++) {
DFS(i, vertices);
int main() {
scanf("%d", &vertices);
initializeGraph(vertices);
scanf("%d", &edges);
addEdge(u, v);
displayGraph(vertices);
scanf("%d", &start);
printf(“\nDFS Traversal:”);
DFS(start, vertices);
printf("\n");
return 0;
}
Set C.
(d) Which Data Structure is Used to Implement the Adjacency Matrix Method?
Why a 2D Array?
• The adjacency matrix is a V × V (vertices × vertices) array, where adj[i][j] stores 1 if there is an edge
between vertex i and vertex j, otherwise it stores 0.
Example Implementation in C:
int adjMatrix[MAX][MAX];
Assignment 4
Set A.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int vertex;
};
newNode->vertex = v;
newNode->next = NULL;
return newNode;
adjList[i] = NULL;
printf("Enter the edges (format: source destination):\n");
newNode->next = adjList[src];
adjList[src] = newNode;
newNode = createNode(src);
newNode->next = adjList[dest];
adjList[dest] = newNode;
}
}
printf("\nAdjacency List:\n");
while (temp) {
temp = temp->next;
printf("\n");
}
}
while (temp) {
outdegree[i]++;
indegree[temp->vertex]++;
temp = temp->next;
printf("\nVertex\tIndegree\tOutdegree\tTotal Degree\n");
for (int i = 0; i < vertices; i++)
printf("%d\t%d\t\t%d\t\t%d\n", i, indegree[i], outdegree[i], totaldegree[i]);
int main() {
int vertices, edges;
scanf("%d", &vertices);
createAdjList(vertices, edges);
displayAdjList(vertices);
calculateDegrees(vertices);
return 0;
}
Set B.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int vertex;
struct Node* next;
};
int visited[MAX];
newNode->vertex = v;
newNode->next = NULL;
return newNode;
adjList[i] = NULL;
visited[i] = 0;
newNode->next = adjList[src];
adjList[src] = newNode;
newNode = createNode(src);
newNode->next = adjList[dest];
adjList[dest] = newNode;
visited[vertex] = 1;
while (temp) {
if (!visited[adjVertex])
DFS(adjVertex);
temp = temp->next;
}
int main() {
scanf("%d", &vertices);
createAdjList(vertices, edges);
scanf("%d", &startVertex);
DFS(startVertex);
printf("\n");
return 0;
}
Set C.
Where is the new node appended in the Breadth-First Search (BFS) OPEN list?
Answer:
• In Breadth-First Search (BFS), the OPEN list (queue) follows the FIFO (First-In-First-Out) principle.
• New nodes are always appended at the rear (end) of the queue.
3. Visit all adjacent (unvisited) nodes and enqueue them at the rear.
#include <stdio.h>
#include <limits.h>
int vertices;
return minIndex;
printf("Edge \tWeight\n");
void primMST() {
int parent[MAX];
int key[MAX];
int mstSet[MAX];
}
key[0] = 0;
parent[0] = -1;
printMST(parent);
}
int main() {
scanf("%d", &vertices);
if (graph[i][j] == 0)
primMST();
return 0;
}
Set B .
#include <stdio.h>
#include <stdlib.h>
struct Edge {
};
struct Graph {
int V, E;
};
struct Subset {
};
graph->V = V;
graph->E = E;
return graph;
if (subsets[i].parent != i)
return subsets[i].parent;
subsets[rootX].parent = rootY;
subsets[rootY].parent = rootX;
else {
subsets[rootY].parent = rootX;
subsets[rootX].rank++;
int e = 0, i = 0;
subsets[v].parent = v;
subsets[v].rank = 0;
if (x != y) {
result[e++] = nextEdge;
unionSets(subsets, x, y);
int main() {
int V, E;
kruskalMST(graph);
return 0;
}
Set C .
#include <stdio.h>
int hasSelfLoop = 0;
hasSelfLoop = 1;
if (!hasSelfLoop)
int main() {
int vertices;
int graph[MAX][MAX];
scanf("%d", &vertices);
scanf("%d", &graph[i][j]);
detectSelfLoops(graph, vertices);
return 0;
}
Assignment 6
Set A .
#include <stdio.h>
#include <limits.h>
min = dist[v];
min_index = v;
return min_index;
int dist[MAX];
int visited[MAX];
dist[i] = INF;
visited[i] = 0;
dist[src] = 0;
if (u == -1) break;
visited[u] = 1;
if (!visited[v] && graph[u][v] && dist[u] != INF && dist[u] + graph[u][v] < dist[v]) {
printSolution(dist, V);
int main() {
int V;
int graph[MAX][MAX];
scanf("%d", &V);
printf("Enter the adjacency cost matrix (use 0 for no edge, except diagonals):\n");
scanf("%d", &graph[i][j]);
if (graph[i][j] == 0 && i != j)
graph[i][j] = INF;
int src;
scanf("%d", &src);
dijkstra(graph, V, src);
return 0;
}
Set B .
#include <stdio.h>
if (dist[i][j] == INF)
printf("INF ");
else
}
printf("\n");
int dist[MAX][MAX];
for (int i = 0; i < V; i++)
printSolution(dist, V);
int main() {
int V;
int graph[MAX][MAX];
scanf("%d", &V);
printf("Enter the adjacency cost matrix (Use 99999 for INF/no edge except diagonals):\n");
scanf("%d", &graph[i][j]);
floydWarshall(graph, V);
return 0;
}
Set C .
#include <stdio.h>
#include <string.h>
#define MAX_PEOPLE 7
#define MAX_NAME_LEN 20
typedef struct {
char name[MAX_NAME_LEN];
char friends[MAX_PEOPLE][MAX_NAME_LEN];
int friendCount;
} Person;
if (strcmp(people[i].name, personName) == 0) {
printf("Friends of %s: ", personName);
if (people[i].friendCount == 0) {
printf("None\n");
} else {
}
printf("\n");
return;
}
int main() {
Person people[MAX_PEOPLE] = {
};
return 0;
}
Assignment 7
Set A .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TABLE_SIZE 10
int hashTable[TABLE_SIZE];
void initializeTable() {
hashTable[i] = -1;
void displayHashTable() {
printf("\nHash Table:\n");
if (hashTable[i] == -1)
else
int sum = 0;
while (key > 0) {
key /= 100;
if (hashTable[index] == -1) {
hashTable[index] = key;
} else {
printf("Collision detected using %s at index %d for key %d! Using Linear Probing.\n", methodName, index, key);
i = (i + 1) % TABLE_SIZE;
if (hashTable[i] == -1) {
hashTable[i] = key;
} else {
int main() {
int n, key;
scanf("%d", &n);
if (n > MAX_KEYS) {
return 1;
int keys[MAX_KEYS];
printf("Enter %d keys: ", n);
scanf("%d", &keys[i]);
initializeTable();
displayHashTable();
initializeTable();
displayHashTable();
initializeTable();
displayHashTable();
return 0;
}
Set B .
#include <stdio.h>
#include <stdlib.h>
#define TABLE_SIZE 10
#define EMPTY -1
int hashTable[TABLE_SIZE];
void initializeTable() {
hashTable[i] = EMPTY;
hashTable[index] = key;
if (hashTable[index] == key) {
return;
}
index = (index + 1) % TABLE_SIZE;
if (hashTable[index] == key) {
hashTable[index] = EMPTY;
return;
void display() {
printf("\nHash Table:\n");
if (hashTable[i] == EMPTY)
else
int main() {
while (1) {
printf("1. Insert\n");
printf("2. Search\n");
printf("3. Delete\n");
printf("4. Display\n");
printf("5. Exit\n");
scanf("%d", &choice);
switch (choice) {
case 1:
scanf("%d", &key);
insert(key);
break;
case 2:
scanf("%d", &key);
search(key);
break;
case 3:
scanf("%d", &key);
delete(key);
break;
case 4:
display();
break;
case 5:
printf("Exiting...\n");
exit(0);
default:
return 0;
}
Set C .
a) Calculate the time complexity of hash table with Linear Probing.
• Time Complexity of Hash Table with Linear Probing
Linear probing is a collision resolution technique in open addressing, where collisions are resolved by
searching for the next available slot in a sequential manner.
• As α increases, the chances of longer probe sequences increase, leading to higher search/insertion
time.
Conclusion
• Best Case: O(1)O(1)O(1) (No collision)
#include <stdlib.h>
#define TABLE_SIZE 10
int key;
struct Node* next;
} Node;
Node* hashTable[TABLE_SIZE];
newNode->key = key;
newNode->next = NULL;
if (hashTable[index] == NULL) {
hashTable[index] = newNode;
} else {
newNode->next = hashTable[index];
hashTable[index] = newNode;
return;
}
temp = temp->next;
if (temp->key == key) {
hashTable[index] = temp->next;
} else {
prev->next = temp->next;
}
free(temp);
return;
prev = temp;
temp = temp->next;
}
printf("Key %d not found in the hash table.\n", key);
}
void display() {
while (temp) {
printf("NULL\n");
int main() {
while (1) {
scanf("%d", &choice);
switch (choice) {
case 1:
scanf("%d", &key);
insert(key);
break;
case 2:
printf("Enter key to search: ");
scanf("%d", &key);
search(key);
break;
case 3:
scanf("%d", &key);
deleteKey(key);
break;
case 4:
display();
break;
case 5:
printf("Exiting program.\n");
return 0;
default:
printf("Invalid choice! Please try again.\n");
return 0;
}
Set B .
#include <stdio.h>
#include <stdlib.h>
#define TABLE_SIZE 10
int key;
struct Node* prev;
}Node;
Node* hashTable[TABLE_SIZE];
}
void insert(int key) {
newNode->key = key;
newNode->prev = NULL;
newNode->next = NULL;
if (hashTable[index] == NULL) {
hashTable[index] = newNode;
} else {
newNode->next = hashTable[index];
hashTable[index]->prev = newNode;
hashTable[index] = newNode;
while (temp) {
if (temp->key == key) {
temp = temp->next;
while (temp) {
if (temp->key == key) {
if (temp->prev == NULL) {
hashTable[index] = temp->next;
if (temp->next) {
temp->next->prev = NULL;
}
} else {
temp->prev->next = temp->next;
if (temp->next) {
temp->next->prev = temp->prev;
}
free(temp);
printf("Key %d deleted successfully.\n", key);
return;
}
temp = temp->next;
}
void display() {
while (temp) {
temp = temp->next;
}
printf("NULL\n");
int main() {
hashTable[i] = NULL;
}
while (1) {
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter key to insert: ");
scanf("%d", &key);
insert(key);
break;
case 2:
scanf("%d", &key);
search(key);
break;
case 3:
scanf("%d", &key);
deleteKey(key);
break;
case 4:
display();
break;
case 5:
printf("Exiting program.\n");
return 0;
default:
return 0;
}
Set C .
#include <stdio.h>
#include <stdlib.h>
}
if (arr[i] >= 0) {
hashTable[arr[i]] = 1;
}
}
int main() {
int S = 7;
findPairs(arr, n, S);
return 0;