Algorithms Lab_20289
Algorithms Lab_20289
Aim:
To write a C program to sort a given set of elements using the Quick Sort method and to determine
the time required to sort the elements.
Algorithm:
1. Quick Sort Algorithm :
Step 1 : Choose a pivot element from the array.
Step 2 : Partition the array into two sub-arrays: elements less than the pivot and elements greater
than the pivot.
Step 3 : Recursively apply the above steps to the sub-arrays.
Step 4 : Combine the sub-arrays and pivot to form the sorted array.
2. Partition Algorithm :
Step 1 : Set the pivot as the last element of the array.
Step 2 : Initialize two pointers: `i` (starting from the left end) and `j` (moving through the array to
compare elements).
Step 3 : Swap elements if they are in the wrong order relative to the pivot.
Step 4 : Move the pivot to its correct position after the partition.
Program in C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int array[], int low, int high) {
int pivot = array[high];
int = low – 1;
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
swap(&array[i], &array[j]);
}}
swap(&array[I + 1], &array[high]);
return (I + 1);
}
void quickSort(int array[], int low, int high) {
if (low < high) {
int pi = partition(array, low, high);
quickSort(array, low, pi – 1);
quickSort(array, pi + 1, high);
}}
void printArray(int array[], int size) {
for (int I = 0; I < size; i++)
printf(“%d “, array[i]);
printf(“\n”);
}
int main() {
int n;
// Input the size of the array
printf(“Enter the number of elements: “);
scanf(“%d”, &n);
int array[n];
// Input the array elements
printf(“Enter the elements:\n”);
for (int I = 0; I < n; i++) {
scanf(“%d”, &array[i]);
}
// Start measuring time
clock_t start, end;
double cpu_time_used;
Start = clock();
quickSort(array, 0, n – 1);
end = clock();
cpu_time_used = ((double)(end – start)) / CLOCKS_PER_SEC;
// Output the sorted array
printf(“Sorted array:\n”);
printArray(array, n);
// Output the time taken
printf(“Time required to sort the array: %f seconds\n”, cpu_time_used);
return 0;
}
Result:
The program successfully implements the Quick Sort algorithm to sort the given set of elements,
and the time required to sort the elements is calculated and displayed.
Exercise 2:
Aim:
To implement the Merge Sort algorithm in C to sort a given set of elements and determine the time
required to sort the elements.
Algorithm:
1. Merge Sort Algorithm :
Step 1 : If the array has only one element, it is already sorted; return.
Step 2 : Divide the array into two halves.
Step 3 : Recursively sort each half.
Step 4 : Merge the two sorted halves into a single sorted array.
2. Merge Function :
Step 1 : Create temporary arrays to hold the two halves.
Step 2 : Compare the elements of the two halves and copy the smaller element into the original
array.
Step 3 : Copy any remaining elements from the temporary arrays to the original array.
Program in C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void merge(int array[], int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int L[n1], R[n2];
for (int i = 0; i < n1; i++)
L[i] = array[left + i];
for (int j = 0; j < n2; j++)
R[j] = array[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
array[k] = L[i];
i++;
} else {
array[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
array[k] = L[i];
i++;
k++;
}
while (j < n2) {
array[k] = R[j];
j++;
k++;
}}
void mergeSort(int array[], int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, mid, right);
}}
void printArray(int array[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", array[i]);
printf("\n");
}
int main() {
int n;
// Input the size of the array
printf("Enter the number of elements: ");
scanf("%d", &n);
int array[n];
// Input the array elements
printf("Enter the elements:\n");
for (int i = 0; i < n; i++) {
scanf("%d", &array[i]);
}
// Start measuring time
clock_t start, end;
double cpu_time_used;
start = clock();
mergeSort(array, 0, n - 1);
end = clock();
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
// Output the sorted array
printf("Sorted array:\n");
printArray(array, n);
// Output the time taken
printf("Time required to sort the array: %f seconds\n", cpu_time_used);
return 0;
}
Input and Output:
Input :
Enter the number of elements: 6
Enter the elements:
38 27 43 3 9 82
Output :
Sorted array:
3 9 27 38 43 82
Time required to sort the array: 0.000018 seconds
Result:
The program successfully implements the Merge Sort algorithm to sort the given set of elements,
and the time required to sort the elements is calculated and displayed.
Exercise 3:
Aim
To implement the 0/1 Knapsack problem using Dynamic Programming.
Algorithm
1. Initialization :
Let `n` be the number of items.
Let `W` be the maximum weight capacity of the knapsack.
Create a 2D array `dp[n+1][W+1]` where `dp[i][j]` represents the maximum value that can be
obtained with the first `i` items and a knapsack capacity of `j`.
2. Dynamic Programming Table Construction :
For each item `i` (from 1 to `n`) and for each weight `w` (from 0 to `W`):
If the weight of the item `i` is less than or equal to `w`, update the table using the following
relation:
\Dp[i][w] = \max(dp[i-1][w], dp[i-1][w - \text{weight}[i-1]] + \text{value}[i-1])
Else, copy the value from the previous row:
\Dp[i][w] = dp[i-1][w]
3. Result Extraction :
The value in `dp[n][W]` will be the maximum value that can be obtained with the given items and
knapsack capacity.
4. Backtracking (optional):
To find the items that make up this maximum value, start from `dp[n][W]` and trace back to see
which items were included.
C Program
#include <stdio.h>
// Function to find the maximum of two integers
int max(int a, int b) {
return (a > b) ? a : b;
}
// Function to implement 0/1 Knapsack using Dynamic Programming
int knapsack(int W, int wt[], int val[], int n) {
int dp[n + 1][W + 1];
// Build table dp[][] in a bottom-up manner
for (int I = 0; I <= n; i++) {
for (int w = 0; w <= W; w++) {
if (I == 0 || w == 0)
Dp[i][w] = 0;
else if (wt[I – 1] <= w)
Dp[i][w] = max(val[I – 1] + dp[I – 1][w – wt[I – 1]], dp[I – 1][w]);
else
Dp[i][w] = dp[I – 1][w];
}}
// Return the maximum value that can be put in a knapsack of capacity W
return dp[n][W];
}
int main() {
int n, W;
// Input number of items and the capacity of the knapsack
printf(“Enter the number of items: “);
scanf(“%d”, &n);
printf(“Enter the capacity of the knapsack: “);
scanf(“%d”, &W);
int val[n], wt[n];
// Input the values and weights of the items
printf(“Enter the values of the items:\n”);
for (int I = 0; I < n; i++) {
printf(“Item %d: “, I + 1);
scanf(“%d”, &val[i]);
}
Input/Output
Input:
Enter the number of items: 3
Enter the capacity of the knapsack: 50
Enter the values of the items:
Item 1: 60
Item 2: 100
Item 3: 120
Enter the weights of the items:
Item 1: 10
Item 2: 20
Item 3: 30
Output:
The maximum value that can be obtained is: 220
Result
The program successfully implements the 0/1 Knapsack problem using Dynamic Programming.
Given the weights and values of items, the program determines the maximum value that can be
obtained within the given capacity of the knapsack. In the provided example, the maximum value
is `220`.
Exercise 4:
Aim
To find the shortest paths from a given vertex in a weighted connected graph to all other vertices
using Dijkstra’s algorithm.
Algorithm
1. Initialization :
- Let `V` be the number of vertices in the graph.
- Let `dist[V]` be an array where `dist[i]` represents the shortest distance from the source vertex to
vertex `i`. Initialize all distances as infinity except for the source vertex, which should be initialized
to `0`.
- Let `sptSet[V]` be a boolean array where `sptSet[i]` is `true` if vertex `i` is included in the shortest
path tree (SPT) and `false` otherwise. Initialize all values in `sptSet` to `false`.
2. Main Loop :
- Repeat for `V-1` times:
- Select the vertex `u` that is not in `sptSet` and has the minimum distance in `dist[]`.
- Mark `u` as included in `sptSet`.
- For each adjacent vertex `v` of `u`, if `v` is not in `sptSet` and there is an edge from `u` to `v`,
and if the total weight of the path from the source to `v` through `u` is less than `dist[v]`, update
`dist[v]`.
3. Result Extraction :
- The array `dist[]` now contains the shortest distances from the source vertex to all other vertices.
C Program
#include <stdio.h>
#include <limits.h>
// Number of vertices in the graph
#define V 9
// Function to find the vertex with the minimum distance value
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;
}
// Function to print the constructed distance array
void printSolution(int dist[], int n) {
printf(“Vertex \t Distance from Source\n”);
for (int I = 0; I < V; i++)
printf(“%d \t\t %d\n”, I, dist[i]);
}
// Function to implement Dijkstra’s single-source shortest path algorithm
void dijkstra(int graph[V][V], int src) {
int dist[V]; // Output array. Dist[i] will hold the shortest distance from src to i
int sptSet[V]; // sptSet[i] will be true if vertex I is included in the shortest path tree
// Initialize all distances as INFINITE and sptSet[] as false
for (int I = 0; I < V; i++)
Dist[i] = INT_MAX, sptSet[i] = 0;
// Distance of source vertex from itself is always 0
Dist[src] = 0;
// Find shortest path for all vertices
for (int count = 0; count < V – 1; count++) {
// Pick the minimum distance vertex from the set of vertices not yet processed
int u = minDistance(dist, sptSet);
// Mark the picked vertex as processed
sptSet[u] = 1;
// Update dist[] value of the adjacent vertices of the picked vertex
for (int v = 0; v < V; v++)
// Update dist[v] only if it is not in sptSet, there is an edge from u to v, and the total weight of path
from src to v through u is smaller than the current value of dist[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];
}
// Print the constructed distance array
printSolution(dist, V);
}
int main() {
/* Let us create the example graph as described in the problem statement */
int graph[V][V] = {{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}};
// Specify the source vertex
int src = 0; // You can change the source vertex as needed
Dijkstra(graph, src);
return 0;
}
Input/Output
Input:
- The graph is represented as an adjacency matrix.
- The source vertex is specified in the code (here, it’s vertex 0).
Output:
Vertex Distance from Source
0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14
Result
The program successfully implements Dijkstra’s algorithm to find the shortest paths from a given
vertex in a weighted connected graph to all other vertices. The output shows the minimum
distances from the source vertex to each of the other vertices in the graph. In the provided example,
starting from vertex 0, the shortest distances to all other vertices are displayed.
Exercise 5:
Aim
To implement and perform various tree traversal algorithms, including Inorder, Preorder, and
Postorder traversals on a binary tree.
Algorithm
1. Inorder Traversal :
- Traverse the left subtree in Inorder.
- Visit the root node.
- Traverse the right subtree in Inorder.
Inorder Sequence : Left, Root, Right
2. Preorder Traversal :
- Visit the root node.
- Traverse the left subtree in Preorder.
- Traverse the right subtree in Preorder.
Preorder Sequence : Root, Left, Right
3. Postorder Traversal :
- Traverse the left subtree in Postorder.
- Traverse the right subtree in Postorder.
- Visit the root node.
Postorder Sequence : Left, Right, Root
C Program
#include <stdio.h>
#include <stdlib.h>
// Definition of a node in the binary tree
struct Node {
int data;
struct Node* left;
struct Node* right;
};
// Function to create a new node
struct Node* newNode(int data) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return(node);
}
// Function to perform Inorder Traversal
void inorderTraversal(struct Node* node) {
if (node == NULL)
return;
// Traverse the left subtree
inorderTraversal(node->left);
// Visit the root
printf(“%d “, node->data);
// Traverse the right subtree
inorderTraversal(node->right);
}
Input/Output
Input:
The binary tree is constructed directly in the code as follows:
1
/ \
2 3
/ \ / \
4 5 6 7
Output:
Inorder Traversal: 4251637
Preorder Traversal: 1 2 4 5 3 6 7
Postorder Traversal: 4 5 2 6 7 3 1
Result
The program successfully implements Inorder, Preorder, and Postorder tree traversal algorithms
on a binary tree. The output displays the sequence of nodes visited for each type of traversal on
the given binary tree.
Exercise 6:
Aim
To find the Minimum Cost Spanning Tree (MCST) of a given undirected graph using Prim’s
algorithm.
Algorithm
1. Initialization :
- Let `V` be the number of vertices in the graph.
- Create an array `key[]` of size `V` to store the minimum weight edge that connects a vertex to
the growing spanning tree. Initialize all values in `key[]` to infinity except for the first vertex,
which should be set to `0`.
- Create an array `parent[]` to store the resulting Minimum Cost Spanning Tree.
- Create a boolean array `mstSet[]` of size `V` to track the vertices included in the Minimum
Spanning Tree (MST). Initialize all values in `mstSet[]` to `false`.
2. Main Loop :
- Repeat for `V-1` times:
- Select the vertex `u` that is not included in `mstSet[]` and has the minimum value in `key[]`.
- Include `u` in `mstSet[]`.
- Update the `key[]` and `parent[]` arrays for the adjacent vertices of `u`. For each adjacent vertex
`v`, if `v` is not included in `mstSet[]`, and the weight of the edge `(u, v)` is smaller than `key[v]`,
update `key[v]` to the weight of the edge `(u, v)` and set `parent[v]` to `u`.
3. Result Extraction :
- The `parent[]` array now represents the Minimum Cost Spanning Tree. The edges are `(parent[i],
i)` for `I = 1` to `V-1`.
C Program
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
// Number of vertices in the graph
#define V 5
// Function to find the vertex with the minimum key value
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;
}
// Function to print the constructed MST stored in parent[]
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]]);
}
// Function to construct and print MST using Prim’s algorithm
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
bool mstSet[V]; // To represent set of vertices not yet included in MST
// Initialize all keys as INFINITE
for (int I = 0; I < V; i++)
Key[i] = INT_MAX, mstSet[i] = false;
// Always include first 1st vertex in MST.
Key[0] = 0; // Make key 0 so that this vertex is picked as the first vertex
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 not yet included in MST
int u = minKey(key, mstSet);
// Add the picked vertex to the MST Set
mstSet[u] = true;
// Update key value and parent index of the adjacent vertices of the picked vertex
for (int v = 0; v < V; v++)
// graph[u][v] is non zero only for adjacent vertices of u
// mstSet[v] is false for vertices not yet included in MST
// Update the key only if graph[u][v] is smaller than key[v]
if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v])
Parent[v] = u, key[v] = graph[u][v];
}
// Print the constructed MST
printMST(parent, graph);
}
int main() {
// Example graph represented as an adjacency matrix
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}};
// Run Prim’s algorithm to find the Minimum Cost Spanning Tree
primMST(graph);
return 0;
}
Input/Output
Input:
- The graph is represented as an adjacency matrix directly in the code:
2 3
(0)-----(1)----(2)
| \ | /
6| 8\ | /7
| \ | /
(3)-----(4)
9
Output:
Edge Weight
0–1 2
1–2 3
0–3 6
1–4 5
Result
The program successfully implements Prim’s algorithm to find the Minimum Cost Spanning Tree
(MCST) of a given undirected graph. The output displays the edges included in the MCST along
with their weights. In the provided example, the edges forming the MCST are `0-1`, `1-2`, `0-3`,
and `1-4` with the total minimum cost being the sum of these edge weights.
Exercise 7:
Aim
To implement the N-Queens problem using backtracking, where the goal is to place `N` queens on
an `N x N` chessboard so that no two queens threaten each other.
Algorithm
1. Initialize the Board :
- Create an `N x N` board, initialized with all zeros, where `0` represents an empty cell and `1`
represents a queen.
2. Recursive Backtracking :
- Start from the leftmost column and try placing a queen in each row one by one in the current
column.
- For every cell, check if it is safe to place a queen. A cell is considered safe if there is no other
queen in the same row, column, or diagonal.
- If placing the queen in a cell leads to a solution (i.e., all queens are placed safely), return `true`.
- If placing the queen does not lead to a solution, backtrack by removing the queen and try the next
cell in the current column.
- If no placement works, return `false`.
3. Solution Extraction :
- If the solution is found, print the board with the queens placed.
C Program
#include <stdio.h>
#include <stdbool.h>
#define N 8 // Change this value for different sizes of the chessboard
// Function to print the solution
void printSolution(int board[N][N]) {
for (int I = 0; I < N; i++) {
for (int j = 0; j < N; j++)
printf(“ %d “, board[i][j]);
printf(“\n”);
}
}
int main() {
solveNQ();
return 0;
}
Input/Output
Input:
The chessboard size `N x N` is defined in the code (`N = 8` for an 8-Queens problem, but can be
changed to any integer).
Output:
For `N = 8`, the program prints one possible solution:
1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
Each `1` represents a queen placed on the board, and `0` represents an empty space.
Result
The program successfully implements the N-Queens problem using backtracking. The output
displays one possible arrangement of queens on the `N x N` chessboard such that no two queens
threaten each other. The solution satisfies the conditions that no two queens share the same row,
column, or diagonal.