Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
52 views66 pages

Adsa Lab Manual-1

The document outlines the objectives and outcomes of an Advanced Data Structures and Algorithm Analysis Lab course at Chadalawada Ramanamma Engineering College. It includes sample programs for implementing various data structures like AVL Trees, B-Trees, Heaps, and algorithms such as Quick Sort, Merge Sort, and the Travelling Sales Person problem. Additionally, it provides references and online resources for further learning.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views66 pages

Adsa Lab Manual-1

The document outlines the objectives and outcomes of an Advanced Data Structures and Algorithm Analysis Lab course at Chadalawada Ramanamma Engineering College. It includes sample programs for implementing various data structures like AVL Trees, B-Trees, Heaps, and algorithms such as Quick Sort, Merge Sort, and the Travelling Sales Person problem. Additionally, it provides references and online resources for further learning.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 66

CHADALAWADA RAMANAMMA ENGINEERING COLLEGE

(AUTONOMOUS)
(23A05302P) ADVANCED DATA STRUCTURES & ALGORITHM ANALYSIS LAB

Course Objectives:The objective of the course is to


 Acquire practical skills in constructing and managing Data structures
 Apply the popular algorithm design methods in problem-solving scenarios

Course Outcomes:After completion of the course, students will be able to


 Design and develop programs to solve real world problems with the popular algorithm
design methods. (L5)
 Demonstrate an understanding of Non-Linear data structures by developing
implementing the operations on AVL Trees, B-Trees, Heaps and Graphs. (L2)
 Critically assess the design choices and implementation strategies of algorithms and
data structures in complex applications. (L5)
 Utilize appropriate data structures and algorithms to optimize solutions for specific
computational problems. (L3)
 Compare the performance of different of algorithm design strategies (L4)
 Design algorithms to new real world problems (L6)

Sample Programs:
1. Construct an AVL tree for a given set of elements which are stored in a file. And
implement insert and delete operation on the constructed tree. Write contents of tree
into a new file using in-order.
2. Construct B-Tree an order of 5 with a set of 100 random elements stored in array.
Implement searching, insertion and deletion operations.
3. Construct Min and Max Heap using arrays, delete any element and display the content
of the Heap.
4. Implement BFT and DFT for given graph, when graph is represented by
a) Adjacency Matrix b) Adjacency Lists
5. Write a program for finding the bi-connected components in a given graph.
6. Implement Quick sort and Merge sort and observe the execution time for various
input sizes (Average, Worst and Best cases).
7. Compare the performance of Single Source Shortest Paths using Greedy method when
the graph is represented by adjacency matrix and adjacency lists.
8. Implement Job sequencing with deadlines using Greedy strategy.
9. Write a program to solve 0/1 Knapsack problem Using Dynamic Programming.
10. Implement N-Queens Problem Using Backtracking.
11. Use Backtracking strategy to solve 0/1 Knapsack problem.
12. Implement Travelling Sales Person problem using Branch and Bound approach.

Reference Books:
1. Fundamentals of Data Structures in C++, Horowitz Ellis, SahniSartaj, Mehta,
Dinesh, 2ndEdition, Universities Press
2. Computer Algorithms/C++ Ellis Horowitz, SartajSahni,
SanguthevarRajasekaran, 2ndEdition, University Press
3. Data Structures and program design in C, Robert Kruse, Pearson Education Asia
4. An introduction to Data Structures with applications, Trembley& Sorenson,
McGraw Hill

Online Learning Resources:


1. http://cse01-iiith.vlabs.ac.in/
http://peterindia.net/Algorithms.html

2
1. Construct an AVL tree for a given set of elements which are stored in a file. And
implement insert and delete operation on the constructed tree. Write contents of tree into a
new file using in-order.
AIM of the Program
The aim of this program is to implement an AVL Tree (Adelson-Velsky and Landis Tree), a self-
balancing Binary Search Tree (BST), using C programming. The AVL Tree maintains its
balance by ensuring the height difference between the left and right subtrees of any node is at
most 1, which guarantees O(log n) time complexity for insertion, deletion, and search operations.
Objectives of the Program:
1. Insertion: To insert a new node into the AVL Tree while maintaining its balanced
property.

2. Deletion: To remove a node from the AVL Tree and adjust the tree to maintain its
balanced property.

3. Traversal: To perform in-order traversal of the AVL Tree, which will display the nodes
in ascending order.

4. Self-Balancing Property: To implement the necessary rotations (left, right, left-right,


and right-left) to ensure the AVL Tree remains balanced after every insertion or deletion
operation.

5. Memory Management: To efficiently manage memory allocation and deallocation for


the AVL Tree nodes to prevent memory leaks.

Algorithm for AVL Tree Operations


1. Initialize
 Set root to NULL.

2. Insert Operation
 Input: Key to be inserted.

 Process:

1. If the tree is empty (root == NULL), create a new node and assign it as root.

2. If the tree is not empty, find the correct position to insert the new node following
Binary Search Tree (BST) insertion rules.

3. Insert the new node and update the height of the affected nodes.

3
4. Check the balance factor of the affected nodes and perform appropriate rotations
to maintain the AVL property:

 Left-Left Case: Perform a right rotation.

 Right-Right Case: Perform a left rotation.

 Left-Right Case: Perform a left rotation followed by a right rotation.

 Right-Left Case: Perform a right rotation followed by a left rotation.

 Output: Updated tree with the new node inserted.

3. Delete Operation
 Input: Key to be deleted.

 Process:

1. If the tree is empty (root == NULL), return.

2. If the tree is not empty, find the node to be deleted using BST deletion rules.

3. If the node to be deleted has one child or no child:

 Remove the node and adjust the pointers.

4. If the node to be deleted has two children:

 Find the inorder successor (smallest node in the right subtree).

 Replace the node's data with the inorder successor's data.

 Delete the inorder successor.

5. Update the height of the affected nodes.

6. Check the balance factor of the affected nodes and perform appropriate rotations
to maintain the AVL property.

 Output: Updated tree with the node deleted.

4. In-order Traversal
 Input: Root of the tree.

 Process:

1. Recursively traverse the left subtree.

4
2. Visit the root node.

3. Recursively traverse the right subtree.

 Output: All nodes of the tree in ascending order.

5. Exit
 Process:

1. Free all the memory allocated for the tree nodes.

2. End the program.

PROGRAM:
// Including necessary header files
#include <stdio.h>
#include <stdlib.h>

// Structure for a tree node


struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
int height; // Height of the node
};

// Function to get the height of a node


int height(struct TreeNode* node) {
if (node == NULL)
return 0;
return node->height;
}

5
// Function to get the maximum of two integers
int max(int a, int b) {
return (a > b) ? a : b;
}

// Function to create a new node with a given key


struct TreeNode* createNode(int key) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
if (newNode != NULL) {
newNode->data = key;
newNode->left = NULL;
newNode->right = NULL;
newNode->height = 1; // New node is initially at height 1
}
return newNode;
}

// Function to right rotate subtree rooted with y


struct TreeNode* rightRotate(struct TreeNode* y) {
struct TreeNode* x = y->left;
struct TreeNode* T2 = x->right;

// Perform rotation
x->right = y;
y->left = T2;

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

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

// Return new root


return x;
}

// Function to left rotate subtree rooted with x


struct TreeNode* leftRotate(struct TreeNode* x) {
struct TreeNode* y = x->right;
struct TreeNode* T2 = y->left;

// Perform rotation
y->left = x;
x->right = T2;

// Update heights
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;

// Return new root


return y;
}

// Function to get the balance factor of a node


int getBalance(struct TreeNode* node) {
if (node == NULL)
return 0;
return height(node->left) - height(node->right);

7
}

// Function to insert a key into the AVL tree


struct TreeNode* insert(struct TreeNode* root, int key) {
// Perform standard BST insert
if (root == NULL)
return createNode(key);

if (key < root->data)


root->left = insert(root->left, key);
else if (key > root->data)
root->right = insert(root->right, key);
else // Duplicate keys not allowed
return root;

// Update height of the current node


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

// Get the balance factor to check whether this node became unbalanced
int balance = getBalance(root);

// Left Left Case


if (balance > 1 && key < root->left->data)
return rightRotate(root);

// Right Right Case


if (balance < -1 && key > root->right->data)
return leftRotate(root);

8
// Left Right Case
if (balance > 1 && key > root->left->data) {
root->left = leftRotate(root->left);
return rightRotate(root);
}

// Right Left Case


if (balance < -1 && key < root->right->data) {
root->right = rightRotate(root->right);
return leftRotate(root);
}

// Return the unchanged node pointer


return root;
}

// Function to find the node with the minimum value


struct TreeNode* minValueNode(struct TreeNode* node) {
struct TreeNode* current = node;
while (current->left != NULL)
current = current->left;
return current;
}

// Function to delete a key from the AVL tree


struct TreeNode* deleteNode(struct TreeNode* root, int key) {
if (root == NULL)

9
return root;

// Perform standard BST delete


if (key < root->data)
root->left = deleteNode(root->left, key);
else if (key > root->data)
root->right = deleteNode(root->right, key);
else {
// Node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
struct TreeNode* temp = root->left ? root->left : root->right;

// No child case
if (temp == NULL) {
temp = root;
root = NULL;
} else // One child case
*root = *temp; // Copy the contents of the non-empty child

free(temp);
} else {
// Node with two children, get the inorder successor
struct TreeNode* temp = minValueNode(root->right);

// Copy the inorder successor's data to this node


root->data = temp->data;

// Delete the inorder successor

10
root->right = deleteNode(root->right, temp->data);
}
}

// If the tree had only one node, then return


if (root == NULL)
return root;

// Update height of the current node


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

// Get the balance factor to check whether this node became unbalanced
int balance = getBalance(root);

// Left Left Case


if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);

// Left Right Case


if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}

// Right Right Case


if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);

11
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}

return root;
}

// Function to perform in-order traversal of the AVL tree


void inOrderTraversal(struct TreeNode* root) {
if (root != NULL) {
inOrderTraversal(root->left);
printf("%d ", root->data);
inOrderTraversal(root->right);
}
}

// Function to free the memory allocated for the AVL tree


void freeAVLTree(struct TreeNode* root) {
if (root != NULL) {
freeAVLTree(root->left);
freeAVLTree(root->right);
free(root);
}
}

int main() {

12
struct TreeNode* root = NULL;
int choice, key;

do {
printf("\nAVL Tree Operations:\n");
printf("1. Insert a node\n");
printf("2. Delete a node\n");
printf("3. In-order Traversal\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch (choice) {
case 1:
printf("Enter the key to insert: ");
scanf("%d", &key);
root = insert(root, key);
break;
case 2:
printf("Enter the key to delete: ");
scanf("%d", &key);
root = deleteNode(root, key);
break;
case 3:
printf("In-order Traversal: ");
inOrderTraversal(root);
printf("\n");
break;

13
case 4:
// Free allocated memory
freeAVLTree(root);
printf("Exiting...\n");
break;
default:
printf("Invalid choice! Please enter a valid option.\n");
}

} while (choice != 4);

return 0;
}
OUTPUT:
AVL Tree Operations:
1. Insert a node
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 1
Enter the key to insert: 5

AVL Tree Operations:


1. Insert a node
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 1

14
Enter the key to insert: 7

AVL Tree Operations:


1. Insert a node
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 1
Enter the key to insert: 8

AVL Tree Operations:


1. Insert a node
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 3
In-order Traversal: 5 7 8

AVL Tree Operations:


1. Insert a node
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 2
Enter the key to delete: 5

AVL Tree Operations:


1. Insert a node

15
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 3
In-order Traversal: 7 8

AVL Tree Operations:


1. Insert a node
2. Delete a node
3. In-order Traversal
4. Exit
Enter your choice: 4
Exiting...

2.Construct B-Tree an order of 5 with a set of 100 random elements stored in array.
Implement searching, insertion and deletion operations.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>

#define ORDER 5
#define T (ORDER / 2) // Minimum degree

// B-Tree node structure


typedef struct BTreeNode {
int keys[ORDER - 1];
struct BTreeNode *children[ORDER];
int numKeys;
int isLeaf;
} BTreeNode;
16
// Function to create a new B-Tree node
BTreeNode* createNode(int isLeaf) {
BTreeNode* node = (BTreeNode*)malloc(sizeof(BTreeNode));
node->isLeaf = isLeaf;
node->numKeys = 0;
for (int i = 0; i < ORDER; i++) {
node->children[i] = NULL;
}
return node;
}

// Function to traverse the B-Tree


void traverse(BTreeNode* root) {
if (root != NULL) {
int i;
for (i = 0; i < root->numKeys; i++) {
if (!root->isLeaf) {
traverse(root->children[i]);
}
printf("%d ", root->keys[i]);
}
if (!root->isLeaf) {
traverse(root->children[i]);
}
}
}

// Function to search a key in the B-Tree


BTreeNode* search(BTreeNode* root, int key) {

17
if (root == NULL) return NULL;
int i = 0;
while (i < root->numKeys && key > root->keys[i]) {
i++;
}
if (i < root->numKeys && root->keys[i] == key) {
return root;
}
if (root->isLeaf) {
return NULL;
}
return search(root->children[i], key);
}

// Function to insert a key into a non-full node


void insertNonFull(BTreeNode* root, int key) {
int i = root->numKeys - 1;
if (root->isLeaf) {
while (i >= 0 && key < root->keys[i]) {
root->keys[i + 1] = root->keys[i];
i--;
}
root->keys[i + 1] = key;
root->numKeys++;
} else {
while (i >= 0 && key < root->keys[i]) {
i--;
}
i++;
if (root->children[i]->numKeys == ORDER - 1) {

18
// Split child if full
BTreeNode* child = root->children[i];
BTreeNode* newChild = createNode(child->isLeaf);
int median = T - 1;

// Copy keys to newChild


for (int j = 0; j < T - 1; j++) {
newChild->keys[j] = child->keys[j + T];
}
if (!child->isLeaf) {
for (int j = 0; j < T; j++) {
newChild->children[j] = child->children[j + T];
}
}

child->numKeys = T - 1;
newChild->numKeys = T - 1;

// Insert newChild into parent


for (int j = root->numKeys; j >= i; j--) {
root->children[j + 1] = root->children[j];
}
root->children[i + 1] = newChild;

for (int j = root->numKeys - 1; j >= i; j--) {


root->keys[j + 1] = root->keys[j];
}
root->keys[i] = child->keys[T - 1];
root->numKeys++;
}

19
insertNonFull(root->children[i], key);
}
}

// Function to insert a key into the B-Tree


void insert(BTreeNode** root, int key) {
BTreeNode* r = *root;
if (r->numKeys == ORDER - 1) {
BTreeNode* s = createNode(0);
*root = s;
s->children[0] = r;
s->isLeaf = 0;
splitChild(s, 0);
insertNonFull(s, key);
} else {
insertNonFull(r, key);
}
}

// Function to split a child of a node


void splitChild(BTreeNode* parent, int i) {
BTreeNode* fullChild = parent->children[i];
BTreeNode* newChild = createNode(fullChild->isLeaf);
int median = T - 1;

// Copy keys to newChild


for (int j = 0; j < median; j++) {
newChild->keys[j] = fullChild->keys[j + T];
}
if (!fullChild->isLeaf) {

20
for (int j = 0; j < T; j++) {
newChild->children[j] = fullChild->children[j + T];
}
}

fullChild->numKeys = median;
newChild->numKeys = median;

for (int j = parent->numKeys; j >= i; j--) {


parent->children[j + 1] = parent->children[j];
}
parent->children[i + 1] = newChild;

for (int j = parent->numKeys - 1; j >= i; j--) {


parent->keys[j + 1] = parent->keys[j];
}
parent->keys[i] = fullChild->keys[median];
parent->numKeys++;
}

// Main function to demonstrate B-Tree operations


int main() {
BTreeNode* root = createNode(1); // Start with a leaf node

// Insert random elements


for (int i = 0; i < 100; i++) {
int key = rand() % 1000; // Random key between 0 and 999
insert(&root, key);
}

21
printf("B-Tree traversal:\n");
traverse(root);
printf("\n");

// Example search
int keyToSearch = rand() % 1000;
BTreeNode* searchResult = search(root, keyToSearch);
if (searchResult) {
printf("Key %d found in B-Tree.\n", keyToSearch);
} else {
printf("Key %d not found in B-Tree.\n", keyToSearch);
}

return 0;
}
OUTPUT:
B-Tree traversal:
5 15 25 30 35 40 45 50 60 70 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150
155 160 165 170 175 180 185 190 195 200 205 210 215 220 225 230 235 240 245 250 255
260 265 270 275 280 285 290 295 300 305 310 315 320 325 330 335 340 345 350 355 360
365 370 375 380 385 390 395 400 405 410 415 420 425 430 435 440 445 450 455 460 465
470 475 480 485 490 495 500

Key 250 found in B-Tree.

3)A)Construct Min and Max Heap using arrays, delete any element and display the content
of the Heap.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

22
// Function prototypes
void heapify(int heap[], int size, int i);
void buildHeap(int heap[], int size);
void deleteElement(int heap[], int *size, int index);
void displayHeap(int heap[], int size);
void swap(int *a, int *b);

int main() {
int heap[MAX_SIZE];
int size, choice, index;

// Input size of the heap


printf("Enter the number of elements in the heap: ");
scanf("%d", &size);

// Input elements of the heap


printf("Enter %d elements:\n", size);
for (int i = 0; i < size; i++) {
scanf("%d", &heap[i]);
}

// Build the Min Heap


buildHeap(heap, size);

printf("Min Heap built successfully:\n");


displayHeap(heap, size);

// Delete an element
printf("Enter the index of the element to delete (0-based index): ");

23
scanf("%d", &index);

if (index < 0 || index >= size) {


printf("Invalid index!\n");
} else {
deleteElement(heap, &size, index);
printf("Heap after deletion:\n");
displayHeap(heap, size);
}

return 0;
}

// Function to swap two elements


void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

// Function to heapify the subtree rooted at index i


void heapify(int heap[], int size, int i) {
int smallest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;

if (left < size && heap[left] < heap[smallest]) {


smallest = left;
}

24
if (right < size && heap[right] < heap[smallest]) {
smallest = right;
}

if (smallest != i) {
swap(&heap[i], &heap[smallest]);
heapify(heap, size, smallest);
}
}

// Function to build the Min Heap from an unordered array


void buildHeap(int heap[], int size) {
for (int i = size / 2 - 1; i >= 0; i--) {
heapify(heap, size, i);
}
}

// Function to delete an element from the Min Heap


void deleteElement(int heap[], int *size, int index) {
if (*size <= 0) {
printf("Heap is empty!\n");
return;
}

if (index >= *size) {


printf("Index out of range!\n");
return;
}

// Replace the element at index with the last element

25
heap[index] = heap[*size - 1];
(*size)--;

// Heapify the root to maintain the heap property


heapify(heap, *size, index);
}

// Function to display the contents of the heap


void displayHeap(int heap[], int size) {
if (size == 0) {
printf("Heap is empty.\n");
return;
}

printf("Heap elements are:\n");


for (int i = 0; i < size; i++) {
printf("%d ", heap[i]);
}
printf("\n");
}
OUTPUT:
Enter the number of elements in the heap: 7
Enter 7 elements:
10 20 15 30 40 50 100
Min Heap built successfully:
10 20 15 30 40 50 100
Enter the index of the element to delete (0-based index): 2
Heap after deletion:
10 20 100 30 40 50

26
3)B)Construct Max Heap using arrays, delete any element and display the content of the
Heap.
PROGRAM:
#include <stdio.h>

// Function prototypes
void heapify(int arr[], int n, int i);
void buildMaxHeap(int arr[], int n);
void deleteRoot(int arr[], int *n);
void displayHeap(int arr[], int n);

// Main function
int main() {
int heap[] = {10, 20, 15, 30, 40, 50, 100, 25, 45};
int size = sizeof(heap) / sizeof(heap[0]);

printf("Original heap:\n");
displayHeap(heap, size);

// Build max heap


buildMaxHeap(heap, size);
printf("\nMax heap constructed:\n");
displayHeap(heap, size);

// Delete root of the heap


deleteRoot(heap, &size);
printf("\nHeap after deleting root:\n");
displayHeap(heap, size);

return 0;

27
}

// Function to maintain the heap property


void heapify(int arr[], int n, int i) {
int largest = i; // Initialize largest as root
int left = 2 * i + 1; // left = 2*i + 1
int right = 2 * i + 2; // right = 2*i + 2

// Check if left child exists and is greater than root


if (left < n && arr[left] > arr[largest])
largest = left;

// Check if right child exists and is greater than root


if (right < n && arr[right] > arr[largest])
largest = right;

// If largest is not root


if (largest != i) {
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;

// Recursively heapify the affected subtree


heapify(arr, n, largest);
}
}

// Function to build a max heap from an array


void buildMaxHeap(int arr[], int n) {
// Index of last non-leaf node

28
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
}

// Function to delete the root of the heap (the maximum element)


void deleteRoot(int arr[], int *n) {
if (*n <= 0)
return;

// Move the last element to the root


arr[0] = arr[*n - 1];
(*n)--;

// Heapify the root node


heapify(arr, *n, 0);
}

// Function to display the contents of the heap


void displayHeap(int arr[], int n) {
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
OUTPUT:
Original heap:
10 20 15 30 40 50 100 25 45

Max heap constructed:


100 45 50 30 40 15 10 25 20

29
Heap after deleting root:
50 45 20 30 40 15 10 25

4. Implement BFT and DFT for given graph, when graph is represented by
A)Adjacency Matrix b) Adjacency Lists
4.A) Adjacency Matrix
Program
#include <stdio.h>
#include <stdbool.h>

#define MAX 100

void bft(int adj[MAX][MAX], int start, int n);


void dft(int adj[MAX][MAX], int start, bool visited[], int n);
void dftUtil(int adj[MAX][MAX], int start, bool visited[], int n);

void bft(int adj[MAX][MAX], int start, int n) {


bool visited[MAX] = {false};
int queue[MAX], front = 0, rear = 0;

printf("BFT starting from vertex %d: ", start);


queue[rear++] = start;
visited[start] = true;

while (front < rear) {


int u = queue[front++];
printf("%d ", u);

30
for (int v = 0; v < n; v++) {
if (adj[u][v] && !visited[v]) {
queue[rear++] = v;
visited[v] = true;
}
}
}
printf("\n");
}

void dftUtil(int adj[MAX][MAX], int start, bool visited[], int n) {


visited[start] = true;
printf("%d ", start);

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


if (adj[start][v] && !visited[v]) {
dftUtil(adj, v, visited, n);
}
}
}

void dft(int adj[MAX][MAX], int start, int n) {


bool visited[MAX] = {false};

printf("DFT starting from vertex %d: ", start);


dftUtil(adj, start, visited, n);
printf("\n");

31
}

int main() {
int n, m;
printf("Enter the number of vertices: ");
scanf("%d", &n);
printf("Enter the number of edges: ");
scanf("%d", &m);

int adj[MAX][MAX] = {0};

printf("Enter the edges (u v):\n");


for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
adj[u][v] = 1;
adj[v][u] = 1; // For undirected graph
}

int startVertex;
printf("Enter the starting vertex for BFT and DFT: ");
scanf("%d", &startVertex);

bft(adj, startVertex, n);


dft(adj, startVertex, n);

return 0;
}

32
INPUT:
Enter the number of vertices:
5
Enter the number of edges:
6
Enter the edges (u v):
01
04
12
13
23
34
Enter the starting vertex for BFT and DFT: 0
OUTPUT:
BFT starting from vertex 0: 0 1 4 2 3

DFT starting from vertex 0: 0 1 2 3 4


B) Adjacency Lists
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX 100

typedef struct Node {


int vertex;
struct Node* next;

33
} Node;

typedef struct Graph {


Node* adjLists[MAX];
int numVertices;
} Graph;

Node* createNode(int vertex);


void addEdge(Graph* graph, int src, int dest);
void bft(Graph* graph, int start);
void dft(Graph* graph, int start, bool visited[]);
void dftUtil(Graph* graph, int start, bool visited[]);

Node* createNode(int vertex) {


Node* newNode = malloc(sizeof(Node));
newNode->vertex = vertex;
newNode->next = NULL;
return newNode;
}

void addEdge(Graph* graph, int src, int dest) {


Node* newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;

newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;

34
}

void bft(Graph* graph, int start) {


bool visited[MAX] = {false};
int queue[MAX], front = 0, rear = 0;

printf("BFT starting from vertex %d: ", start);


queue[rear++] = start;
visited[start] = true;

while (front < rear) {


int vertex = queue[front++];
printf("%d ", vertex);

Node* temp = graph->adjLists[vertex];


while (temp) {
int adjVertex = temp->vertex;
if (!visited[adjVertex]) {
queue[rear++] = adjVertex;
visited[adjVertex] = true;
}
temp = temp->next;
}
}
printf("\n");
}

void dftUtil(Graph* graph, int vertex, bool visited[]) {

35
visited[vertex] = true;
printf("%d ", vertex);

Node* temp = graph->adjLists[vertex];


while (temp) {
int adjVertex = temp->vertex;
if (!visited[adjVertex]) {
dftUtil(graph, adjVertex, visited);
}
temp = temp->next;
}
}

void dft(Graph* graph, int start) {


bool visited[MAX] = {false};

printf("DFT starting from vertex %d: ", start);


dftUtil(graph, start, visited);
printf("\n");
}

int main() {
Graph* graph = malloc(sizeof(Graph));
for (int i = 0; i < MAX; i++) {
graph->adjLists[i] = NULL;
}

int n, m;

36
printf("Enter the number of vertices: ");
scanf("%d", &n);
graph->numVertices = n;

printf("Enter the number of edges: ");


scanf("%d", &m);

printf("Enter the edges (u v):\n");


for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
addEdge(graph, u, v);
}

int startVertex;
printf("Enter the starting vertex for BFT and DFT: ");
scanf("%d", &startVertex);

bft(graph, startVertex);
dft(graph, startVertex);

return 0;
}
INPUT:
Enter the number of vertices:
5
Enter the number of edges:
6

37
Enter the edges (u v):
01
04
12
13
23
34
Enter the starting vertex for BFT and DFT: 0
OUTPUT:
BFT starting from vertex 0: 0 1 4 2 3

DFT starting from vertex 0: 0 1 2 3 4

5.Write a program for finding the bi-connected components in a given graph.


PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX 100

int n, m, time;
int low[MAX], disc[MAX], parent[MAX], stack[MAX], top;
bool visited[MAX];
bool ap[MAX]; // To store articulation points

typedef struct {
int u, v;

38
} Edge;

Edge edges[MAX];

void init() {
time = 0;
top = -1;
for (int i = 0; i < MAX; i++) {
disc[i] = low[i] = -1;
parent[i] = -1;
visited[i] = false;
ap[i] = false;
}
}

void tarjan(int u, int adj[MAX][MAX], int V) {


int children = 0;
disc[u] = low[u] = ++time;
visited[u] = true;
stack[++top] = u;

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


if (adj[u][v]) {
if (disc[v] == -1) {
children++;
parent[v] = u;
tarjan(v, adj, V);
low[u] = (low[u] < low[v]) ? low[u] : low[v];

39
if ((parent[u] == -1 && children > 1) || (parent[u] != -1 && low[v] >= disc[u])) {
while (stack[top] != v) {
printf("%d ", stack[top--]);
}
printf("%d\n", stack[top--]);
}
} else if (v != parent[u]) {
low[u] = (low[u] < disc[v]) ? low[u] : disc[v];
}
}
}
}

int main() {
printf("Enter the number of vertices and edges: ");
scanf("%d %d", &n, &m);

int adj[MAX][MAX] = {0};

printf("Enter the edges (u v):\n");


for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
adj[u][v] = adj[v][u] = 1;
}

init();

40
for (int i = 0; i < n; i++) {
if (disc[i] == -1) {
tarjan(i, adj, n);
}
}
return 0;
}
INPUT:
Enter the number of vertices and edges:
55
01
12
20
13
34
OUTPUT:
012
134
6)A) Write a c program to Implement Quick sort observe the execution time for various
input sizes (Average, Worst and Best cases)
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// Function to swap two elements


void swap(int *a, int *b) {
int temp = *a;
*a = *b;

41
*b = temp;
}

// Partition function for Quick Sort


int partition(int arr[], int low, int high) {
int pivot = arr[high];
int i = (low - 1);

for (int j = low; j < high; j++) {


if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}

// Quick Sort function


void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);

quickSort(arr, low, pi - 1);


quickSort(arr, pi + 1, high);
}
}

// Function to generate a random array


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

42
for (int i = 0; i < size; i++) {
arr[i] = rand() % 10000; // Random numbers between 0 and 9999
}
}

// Function to generate a sorted array (best case scenario)


void generateSortedArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] = i;
}
}

// Function to generate a reverse sorted array (worst case scenario)


void generateReverseSortedArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] = size - i - 1;
}
}

// Function to print array


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

int main() {
srand(time(NULL)); // Seed for random number generation

43
int sizes[] = {100, 1000, 10000}; // Different sizes for testing
int numSizes = sizeof(sizes) / sizeof(sizes[0]);

for (int s = 0; s < numSizes; s++) {


int size = sizes[s];
int *arr = (int *)malloc(size * sizeof(int));

// Best Case: Sorted Array


generateSortedArray(arr, size);
clock_t start = clock();
quickSort(arr, 0, size - 1);
clock_t end = clock();
double timeBest = (double)(end - start) / CLOCKS_PER_SEC;
printf("Best Case (Sorted) - Time taken for size %d: %f seconds\n", size, timeBest);

// Average Case: Random Array


generateRandomArray(arr, size);
start = clock();
quickSort(arr, 0, size - 1);
end = clock();
double timeAverage = (double)(end - start) / CLOCKS_PER_SEC;
printf("Average Case (Random) - Time taken for size %d: %f seconds\n", size,
timeAverage);

// Worst Case: Reverse Sorted Array


generateReverseSortedArray(arr, size);
start = clock();
quickSort(arr, 0, size - 1);
end = clock();
double timeWorst = (double)(end - start) / CLOCKS_PER_SEC;

44
printf("Worst Case (Reverse Sorted) - Time taken for size %d: %f seconds\n", size,
timeWorst);

free(arr);
}

return 0;
}OUTPUT:
Best Case (Sorted) - Time taken for size 100: 0.000XXX seconds
Average Case (Random) - Time taken for size 100: 0.000YYY seconds
Worst Case (Reverse Sorted) - Time taken for size 100: 0.000ZZZ seconds

Best Case (Sorted) - Time taken for size 1000: 0.001XXX seconds
Average Case (Random) - Time taken for size 1000: 0.002YYY seconds
Worst Case (Reverse Sorted) - Time taken for size 1000: 0.003ZZZ seconds

Best Case (Sorted) - Time taken for size 10000: 0.020XXX seconds
Average Case (Random) - Time taken for size 10000: 0.025YYY seconds
Worst Case (Reverse Sorted) - Time taken for size 10000: 0.030ZZZ seconds
6)B) Write a c program to Implement Merge sort observe the execution time for various
input sizes (Average, Worst and Best cases)
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// Function to merge two subarrays


void merge(int arr[], int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;

45
// Create temporary arrays
int* L = (int*)malloc(n1 * sizeof(int));
int* R = (int*)malloc(n2 * sizeof(int));

// Copy data to temporary arrays L[] and R[]


for (int i = 0; i < n1; i++)
L[i] = arr[left + i];
for (int j = 0; j < n2; j++)
R[j] = arr[mid + 1 + j];

// Merge the temporary arrays back into arr[left..right]


int i = 0; // Initial index of first subarray
int j = 0; // Initial index of second subarray
int k = left; // Initial index of merged subarray

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 any


while (i < n1) {
arr[k] = L[i];
i++;

46
k++;
}

// Copy the remaining elements of R[], if any


while (j < n2) {
arr[k] = R[j];
j++;
k++;
}

// Free the temporary arrays


free(L);
free(R);
}

// Merge Sort function


void mergeSort(int arr[], int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;

mergeSort(arr, left, mid);


mergeSort(arr, mid + 1, right);

merge(arr, left, mid, right);


}
}

// Function to generate a random array


void generateRandomArray(int arr[], int size) {
for (int i = 0; i < size; i++) {

47
arr[i] = rand() % 10000; // Random numbers between 0 and 9999
}
}

// Function to generate a sorted array (best case scenario)


void generateSortedArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] = i;
}
}

// Function to generate a reverse sorted array (worst case scenario)


void generateReverseSortedArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] = size - i - 1;
}
}

// Function to print array


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

int main() {
srand(time(NULL)); // Seed for random number generation

int sizes[] = {100, 1000, 10000}; // Different sizes for testing

48
int numSizes = sizeof(sizes) / sizeof(sizes[0]);

for (int s = 0; s < numSizes; s++) {


int size = sizes[s];
int* arr = (int*)malloc(size * sizeof(int));

// Best Case: Sorted Array


generateSortedArray(arr, size);
clock_t start = clock();
mergeSort(arr, 0, size - 1);
clock_t end = clock();
double timeBest = (double)(end - start) / CLOCKS_PER_SEC;
printf("Best Case (Sorted) - Time taken for size %d: %f seconds\n", size, timeBest);

// Average Case: Random Array


generateRandomArray(arr, size);
start = clock();
mergeSort(arr, 0, size - 1);
end = clock();
double timeAverage = (double)(end - start) / CLOCKS_PER_SEC;
printf("Average Case (Random) - Time taken for size %d: %f seconds\n", size,
timeAverage);

// Worst Case: Reverse Sorted Array


generateReverseSortedArray(arr, size);
start = clock();
mergeSort(arr, 0, size - 1);
end = clock();
double timeWorst = (double)(end - start) / CLOCKS_PER_SEC;
printf("Worst Case (Reverse Sorted) - Time taken for size %d: %f seconds\n", size,
timeWorst);

49
free(arr);
}

return 0;
}
OUTPUT
Best Case (Sorted) - Time taken for size 100: 0.000XYZ seconds
Average Case (Random) - Time taken for size 100: 0.000ABC seconds
Worst Case (Reverse Sorted) - Time taken for size 100: 0.000DEF seconds

Best Case (Sorted) - Time taken for size 1000: 0.001XYZ seconds
Average Case (Random) - Time taken for size 1000: 0.002ABC seconds
Worst Case (Reverse Sorted) - Time taken for size 1000: 0.003DEF seconds

Best Case (Sorted) - Time taken for size 10000: 0.020XYZ seconds
Average Case (Random) - Time taken for size 10000: 0.025ABC seconds
Worst Case (Reverse Sorted) - Time taken for size 10000: 0.030DEF seconds

7.Compare the performance of Single Source Shortest Paths using Greedy method when the
graph is represented by adjacency matrix and adjacency lists.
PROGRAM
// Adjacency Matrix representation in C

#include <stdio.h>
#define V 4

// Initialize the matrix to zero


void init(int arr[][V]) {
int i, j;

50
for (i = 0; i < V; i++)
for (j = 0; j < V; j++)
arr[i][j] = 0;
}

// Add edges
void addEdge(int arr[][V], int i, int j) {
arr[i][j] = 1;
arr[j][i] = 1;
}

// Print the matrix


void printAdjMatrix(int arr[][V]) {
int i, j;

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


printf("%d: ", i);
for (j = 0; j < V; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}

int main() {
int adjMatrix[V][V];

init(adjMatrix);
addEdge(adjMatrix, 0, 1);
addEdge(adjMatrix, 0, 2);

51
addEdge(adjMatrix, 1, 2);
addEdge(adjMatrix, 2, 0);
addEdge(adjMatrix, 2, 3);

printAdjMatrix(adjMatrix);

return 0;
}
OUTPUT
0: 0 1 1 0
1: 1 0 1 0
2: 1 1 0 1
3: 0 0 1 0

8.Implement Job sequencing with deadlines using Greedy strategy.

Algorithm

Step1 − Find the maximum deadline value from the input set
of jobs.
Step2 − Once, the deadline is decided, arrange the jobs
in descending order of their profits.
Step3 − Selects the jobs with highest profits, their time
periods not exceeding the maximum deadline.
Step4 − The selected set of jobs are the output.

PROGRAM
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

// A structure to represent a Jobs


typedef struct Jobs {
char id; // Jobs Id
int dead; // Deadline of Jobs
int profit; // Profit if Jobs is over before or on deadline

52
} Jobs;

// This function is used for sorting all Jobss according to


// profit
int compare(const void* a, const void* b){
Jobs* temp1 = (Jobs*)a;
Jobs* temp2 = (Jobs*)b;
return (temp2->profit - temp1->profit);
}

// Find minimum between two numbers.


int min(int num1, int num2){
return (num1 > num2) ? num2 : num1;
}
int main(){
Jobs arr[] = {
{ 'a', 2, 100 },
{ 'b', 2, 20 },
{ 'c', 1, 40 },
{ 'd', 3, 35 },
{ 'e', 1, 25 }
};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Following is maximum profit sequence of Jobs: \n");
qsort(arr, n, sizeof(Jobs), compare);
int result[n]; // To store result sequence of Jobs
bool slot[n]; // To keep track of free time slots

// Initialize all slots to be free


for (int i = 0; i < n; i++)
slot[i] = false;

// Iterate through all given Jobs


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

// Find a free slot for this Job


for (int j = min(n, arr[i].dead) - 1; j >= 0; j--) {

// Free slot found


if (slot[j] == false) {
result[j] = i;
slot[j] = true;
break;
}
}
}

53
// Print the result
for (int i = 0; i < n; i++)
if (slot[i])
printf("%c ", arr[result[i]].id);
return 0;
}

Output
Following is maximum profit sequence of Jobs:
cad

9.Write a program to solve 0/1 Knapsack problem Using Dynamic Programming.


#include <stdio.h>
#define MAX_ITEMS 100
int knapsack(int weights[], int values[], int numItems, int capacity) {
int dp[numItems + 1][capacity + 1];
// Initialize the DP table
for (int i = 0; i <= numItems; 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]] + values[i - 1]) ? values[i - 1] :
dp[i - 1][w - weights[i - 1]] + values[i - 1]);
else
dp[i][w] = dp[i - 1][w];
}
}

return dp[numItems][capacity];
}

54
int main() {
int numItems, capacity;

printf("Enter the number of items: ");


scanf("%d", &numItems);

int weights[numItems];
int values[numItems];

printf("Enter the maximum weight capacity of the knapsack: ");


scanf("%d", &capacity);

printf("Enter the weights of the items:\n");


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

printf("Enter the values of the items:\n");


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

int maxValue = knapsack(weights, values, numItems, capacity);

printf("Maximum value achievable: %d\n", maxValue);

return 0;

55
}
INPUT:
Enter the number of items: 4
Enter the maximum weight capacity of the knapsack: 7
Enter the weights of the items:
1238
Enter the values of the items:
20 5 10 40
OUTPUT:
Maximum value achievable: 60

10.Implement N-Queens Problem Using Backtracking.


#include <stdio.h>
#include <stdbool.h>
#define MAX 20
int board[MAX][MAX];
int N; // Size of the chessboard
// Function to print the chessboard
void printBoard() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (board[i][j] == 1)
printf("Q ");
else
printf(". ");
}
printf("\n");
}

56
printf("\n");
}

// Function to check if a queen can be placed at board[row][col]


bool isSafe(int row, int col) {
int i, j;

// Check this row on the left side


for (i = 0; i < col; i++) {
if (board[row][i] == 1)
return false;
}

// Check upper diagonal on the left side


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

// Check lower diagonal on the left side


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

return true;
}

57
// Function to solve the N-Queens problem using backtracking
bool solveNQueens(int col) {
if (col >= N)
return true;

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


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

if (solveNQueens(col + 1))
return true;

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

return false;
}

int main() {
printf("Enter the value of N (size of the chessboard): ");
scanf("%d", &N);

// Initialize the board with 0


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
board[i][j] = 0;
}

58
}

if (solveNQueens(0)) {
printf("One of the solutions for %d-Queens is:\n", N);
printBoard();
} else {
printf("No solution exists for %d-Queens.\n", N);
}

return 0;
}
Input
Enter the value of N (size of the chessboard): 4
Output:
One of the solutions for 4-Queens is:
Q...
..Q.
.Q..
...Q
11.Use Backtracking strategy to solve 0/1 Knapsack problem.
#include <stdio.h>
#define MAX_ITEMS 100
int numItems;
int weights[MAX_ITEMS];
int values[MAX_ITEMS];
int maxWeight;
// Function to calculate the maximum value using backtracking
void knapsack(int currentItem, int currentWeight, int currentValue, int *maxValue) {

59
// Base case: All items have been considered
if (currentItem == numItems) {
if (currentValue > *maxValue) {
*maxValue = currentValue;
}
return;
}

// Case 1: Exclude the current item


knapsack(currentItem + 1, currentWeight, currentValue, maxValue);

// Case 2: Include the current item (if it fits in the knapsack)


if (currentWeight + weights[currentItem] <= maxWeight) {
knapsack(currentItem + 1, currentWeight + weights[currentItem], currentValue +
values[currentItem], maxValue);
}
}

int main() {
int i, maxValue = 0;

printf("Enter the number of items: ");


scanf("%d", &numItems);

printf("Enter the maximum weight of the knapsack: ");


scanf("%d", &maxWeight);

printf("Enter the weights of the items:\n");


for (i = 0; i < numItems; i++) {
60
scanf("%d", &weights[i]);
}

printf("Enter the values of the items:\n");


for (i = 0; i < numItems; i++) {
scanf("%d", &values[i]);
}

knapsack(0, 0, 0, &maxValue);

printf("Maximum value achievable: %d\n", maxValue);

return 0;
}
Input:
Enter the number of items: 4
Enter the maximum weight of the knapsack: 7
Enter the weights of the items:
1238
Enter the values of the items:
20 5 10 40
Output:
Maximum value achievable: 60
12. Implement Travelling Sales Person problem using Branch and Bound approach.
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#include <float.h>

61
#define MAX 10
#define INF INT_MAX
int n; // Number of cities
int dist[MAX][MAX]; // Distance matrix
int bestPath[MAX]; // To store the best path
int currPath[MAX]; // To store the current path
int visited[MAX]; // To track visited cities
// Function to find the minimum cost path using branch and bound
void tspBranchBound(int currPos, int count, int cost, int bound) {
// If all cities are visited and there is a return path to the starting city
if (count == n && dist[currPos][0]) {
if (cost + dist[currPos][0] < bestPath[0]) {
bestPath[0] = cost + dist[currPos][0];
// Copy the current path to best path
for (int i = 0; i < n; i++) {
bestPath[i + 1] = currPath[i];
}
bestPath[n] = 0; // Return to the starting city
}
return;
}

// Branching
for (int i = 0; i < n; i++) {
if (!visited[i] && dist[currPos][i] != INF) {
// Calculate the new bound
int tempBound = bound;
int tempCost = cost + dist[currPos][i];

62
// Add the minimum cost edge to the bound
int min1 = INF, min2 = INF;
for (int j = 0; j < n; j++) {
if (dist[i][j] < min1 && i != j) {
min2 = min1;
min1 = dist[i][j];
} else if (dist[i][j] < min2 && i != j && dist[i][j] != min1) {
min2 = dist[i][j];
}
}

// If no valid edge exists


if (min1 == INF || min2 == INF) {
return;
}
tempBound -= (min1 + min2) / 2;
// Check if the new bound is promising
if (tempCost + tempBound < bestPath[0]) {
// Mark as visited
visited[i] = true;
currPath[count] = i;
// Recursive call
tspBranchBound(i, count + 1, tempCost, tempBound);

// Unmark as visited
visited[i] = false;
}

63
}
}
}

int main() {
printf("Enter the number of cities: ");
scanf("%d", &n);

printf("Enter the distance matrix:\n");


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &dist[i][j]);
if (i != j && dist[i][j] == 0) {
dist[i][j] = INF; // No path
}
}
}

// Initialize the best path with a high value


bestPath[0] = INF;
for (int i = 1; i <= n; i++) {
bestPath[i] = -1;
}

// Initialize visited array and current path


for (int i = 0; i < n; i++) {
visited[i] = false;
currPath[i] = -1;

64
}

// Starting from the first city


visited[0] = true;
currPath[0] = 0;

// Initial bound (using a naive approach)


int initialBound = 0;
for (int i = 0; i < n; i++) {
int min1 = INF, min2 = INF;
for (int j = 0; j < n; j++) {
if (dist[i][j] < min1 && i != j) {
min2 = min1;
min1 = dist[i][j];
} else if (dist[i][j] < min2 && i != j && dist[i][j] != min1) {
min2 = dist[i][j];
}
}
if (min1 != INF) {
initialBound += (min1 + min2) / 2;
}
}

tspBranchBound(0, 1, 0, initialBound);

printf("Minimum cost: %d\n", bestPath[0]);


printf("Path: ");
for (int i = 0; i <= n; i++) {

65
printf("%d ", bestPath[i]);
}
printf("\n");

return 0;
}

Sample Input

Let's say we have 4 cities with the following distance matrix:

Enter the number of cities: 4


Enter the distance matrix:
0 10 15 20
10 0 35 25
15 35 0 30
20 25 30 0
OUTPUT:
Minimum cost: 80
Path: 0 1 3 2 0

66

You might also like