Lab File - DAA
Lab File - DAA
Index
Page |3
Sr.
Page
No Name of Experiment Date of Experiment Signature of Faculty
No.
.
To short a given array
using: 23/08/24
4. Count Sort 18
Radix Sort 30/08/24
Bucket Sort
To implement Binary
06/09/24
5. Tree Algorithm on the 23
given set of elements.
To implement balanced
06/09/24
Binary Search Tree
6. 26
Algorithm on the given
set of elements.
To implement BTree
8. Algorithm on the given 36 13/09/24
set of elements.
To implement Greedy
Algorithm Approach on
9. 40 21/09/24
Minimum Spanning
Tree (MST).
To implement Knap
Sack Problem using
10. 44 21/09/24
Greedy Algorithm
approach.
To implement Travelling
11 Salesman Problem using 46 28/09/24
Greedy Approach.
To implement Coin
Sequence Problem of
12 finding minimum 48 28/09/24
number of coins through
Greedy Approach.
Page |4
Experiment no. 1
Aim: To implement Linear and Binary search algorithms and compute their running
time for worst, best and average cases.
#include <stdio.h>
// Driver code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
int result = search(arr, N, x);
(result == -1)
? printf("Element is not present in array")
: printf("Element is present at index %d", result);
return 0;
}
Page |5
Output:
Output:
Time Complexity:
Best Case: In the best case, the key might be present at the first index. So the best case
complexity is O(1)
Worst Case: In the worst case, the key might be present at the last index i.e., opposite to
the end from which the search has started in the list. So the worst-case complexity is
O(N) where N is the size of the list.
Average Case: O(N)
low = mid + 1;
// Driver code
int main(void){
int arr[] = { 2, 3, 4, 10, 40 };
int n = sizeof(arr) / sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n - 1, x);
if(result == -1){
printf("Element is not present in array");
}
else
printf("Element is present at index %d",result);
// in right subarray
return binarySearch(arr, mid + 1, high, x);
}
// Driver code
int main()
{
int arr[] = { 2, 3, 4, 10, 40 };
int n = sizeof(arr) / sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n - 1, x);
if (result == -1) printf("Element is not present in array");
else printf("Element is present at index %d", result);
return 0;
}
Time Complexity:
Best Case: O(1)
Average Case: O(log N)
Worst Case: O(log N)
Output:
Page |8
Experiment no. 2
Aim: To sort a given set of n integer elements using the following iterative sorting
algorithms and compute their time complexity for worst case, average case and best
case. Run the program for varied values of n> 5000 and record the time taken to sort.
● Selection Sort
● Insertion Sort
● Bubble Sort
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
free(arrCopy);
}
int main() {
srand(time(NULL));
free(arr);
}
return 0;
}
Best-case: O(n2), best case occurs when the array is already sorted. (where n is the
number of integers in an array)
Average-case: O(n2), the average case arises when the elements of the array are in a
disordered or random order, without a clear ascending or descending pattern.
Worst-case: O(n2), The worst-case scenario arises when we need to sort an array in
ascending order, but the array is initially in descending order.
Best case: O(n) , If the list is already sorted, where n is the number of elements in the
list.
Average case: O(n2 ) , If the list is randomly ordered
Worst case: O(n2 ) , If the list is in reverse order
Output:
Experiment no. 3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
i++;
k++;
}
}
}
free(arrCopy);
}
free(arrCopy);
}
int main() {
srand(time(NULL));
P a g e | 16
free(arr);
}
return 0;
}
The time complexity of Heap Sort in both best case and worst case scenarios is O(n log
n).
Output:
Experiment no. 4
Aim: To short a given array using:
Count Sort
Radix Sort
Bucket Sort
Count Sort:
#include<stdio.h>
#include<limits.h>
#include<stdlib.h>
i=0;
j=0;
while(i<=max){
if(count[i]>0){
A[j] = i;
count[i] = count[i] - 1;
j++;
}
else{
i++;
}
P a g e | 19
int main(){
int A[] = {23,78,45,8,32,56};
printf("Original Array: \n");
int n = 6;
printArray(A, n);
return 0;
Output:
P a g e | 20
Radix Sort:
#include <stdio.h>
// Driver code
int main() {
int arr[] = {2546, 124, 6, 1230, 431, 126};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Original Array: \n");
printArray(arr, n);
// Function call
radixSort(arr, n);
printf("Sorted Array: \n");
printArray(arr, n);
return 0;
}
Output:
P a g e | 22
Bucket Sort:
#include <stdio.h>
void bucketsort(int a[], int n){ // function to implement bucket sort
int max = a[0]; // get the maximum element in the array
for (int i = 1; i < n; i++)
if (a[i] > max)
max = a[i];
int b[max], i;
for (int i = 0; i <= max; i++) {
b[i] = 0;
}
for (int i = 0; i < n; i++) {
b[a[i]]++;
}
for (int i = 0, j = 0; i <= max; i++) {
while (b[i] > 0) {
a[j++] = i;
b[i]--;
}
}
}
int main(){
int a[] = {12, 45, 33, 87, 56, 9, 11, 7, 67};
int n = sizeof(a) / sizeof(a[0]); // n is the size of array
printf("Before sorting array elements are: \n");
for (int i = 0; i < n; ++i)
printf("%d ", a[i]);
bucketsort(a, n);
printf("\nAfter sorting array elements are: \n");
for (int i = 0; i < n; ++i)
printf("%d ", a[i]);
}
Output:
P a g e | 23
Experiment no. 5
A Binary Tree Data Structure is a hierarchical data structure in which each node has at
most two children, referred to as the left child and the right child. It is commonly used in
computer science for efficient storage and retrieval of data, with various operations such
as insertion, deletion, and traversal.
Tree Traversal refers to the process of visiting or accessing each node of the tree exactly
once in a certain order. Tree traversal algorithms help us to visit and process all the
nodes of the tree. Since tree is not a linear data structure, there are multiple nodes
which we can visit after visiting a certain node. There are multiple tree traversal
techniques which decide the order in which the nodes of the tree are to be visited.
Traversal:
// Tree traversal in C
#include <stdio.h>
#include <stdlib.h>
struct node {
int item;
struct node* left;
struct node* right;
};
// Inorder traversal
void inorderTraversal(struct node* root) {
if (root == NULL) return;
inorderTraversal(root->left);
printf("%d ->", root->item);
inorderTraversal(root->right);
}
// Preorder traversal
void preorderTraversal(struct node* root) {
if (root == NULL) return;
printf("%d ->", root->item);
preorderTraversal(root->left);
P a g e | 24
preorderTraversal(root->right);
}
// Postorder traversal
void postorderTraversal(struct node* root) {
if (root == NULL) return;
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ->", root->item);
}
return newNode;
}
int main() {
struct node* root = createNode(1);
insertLeft(root, 2);
insertRight(root, 3);
insertLeft(root->left, 4);
The time complexity of binary tree traversal depends on the type of traversal and the
structure of the tree:
Postorder traversal:
The time complexity for this traversal is O(n), where n is the size of the binary tree.
Output:
P a g e | 26
Experiment no. 6
Aim: To implement balanced Binary Search Tree Algorithm on the given set of
elements.
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct Node* newNode(int key)
{
struct Node* node = (struct Node*)
malloc(sizeof(struct Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
return(node);
}
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left),
height(y->right)) + 1;
x->height = max(height(x->left),
height(x->right)) + 1;
// 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;
{
/* 1. Perform the normal BST insertion */
if (node == NULL)
return(newNode(key));
printf("\n");
return 0;
}
P a g e | 30
The time complexity for searching, inserting, and deleting in an AVL tree is O(log n),
where n is the number of nodes in the tree. This is because AVL trees are self-balancing
binary search trees that maintain a height of log n.
In contrast, a binary search tree that is not balanced could degenerate into a linked list in
the worst case, resulting in a time complexity of O(n) for these operations.
Output:
P a g e | 31
Experiment no. 7
Aim: To implement Red Black Tree algorithm on the given set of elements.
grand_parent_pt = pt->p->p;
/* Case : A
Parent of pt is left child
of Grand-parent of
pt */
if (parent_pt == grand_parent_pt->l)
{
/* Case : 1
The uncle of pt is also red
Only Recoloring required */
if (uncle_pt != NULL && uncle_pt->c == 1)
{
grand_parent_pt->c = 1;
parent_pt->c = 0;
uncle_pt->c = 0;
pt = grand_parent_pt;
}
else {
/* Case : 2
pt is right child of its parent
Left-rotation required */
if (pt == parent_pt->r) {
leftrotate(parent_pt);
pt = parent_pt;
parent_pt = pt->p;
}
/* Case : 3
pt is left child of its parent
Right-rotation required */
rightrotate(grand_parent_pt);
int t = parent_pt->c;
parent_pt->c = grand_parent_pt->c;
grand_parent_pt->c = t;
pt = parent_pt;
}
}
/* Case : B
Parent of pt is right
child of Grand-parent of
pt */
else {
P a g e | 34
/* Case : 1
The uncle of pt is also red
Only Recoloring required */
if ((uncle_pt != NULL) && (uncle_pt->c == 1))
{
grand_parent_pt->c = 1;
parent_pt->c = 0;
uncle_pt->c = 0;
pt = grand_parent_pt;
}
else {
/* Case : 2
pt is left child of its parent
Right-rotation required */
if (pt == parent_pt->l) {
rightrotate(parent_pt);
pt = parent_pt;
parent_pt = pt->p;
}
/* Case : 3
pt is right child of its parent
Left-rotation required */
leftrotate(grand_parent_pt);
int t = parent_pt->c;
parent_pt->c = grand_parent_pt->c;
grand_parent_pt->c = t;
pt = parent_pt;
}
}
}
}
// driver code
int main()
{
P a g e | 35
int n = 7;
int a[7] = { 7, 6, 5, 4, 3, 2, 1 };
return 0;
}
Red-black trees have logarithmic average and worst-case time complexity for insertion,
search, and deletion. The time complexity for insertion is (log(N)), where (N) is the
number of nodes in the tree. The average time complexity for rebalancing is (O(1)), and
the worst-case complexity is (O(logn)).
Output:
P a g e | 36
Experiment no. 8
Aim: To implement BTree Algorithm on the given set of elements.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct BTreeNode {
int num_keys; // Number of keys currently in the node
int keys[M-1]; // Array of keys
struct BTreeNode *children[M]; // Array of child pointers
bool is_leaf; // True if node is a leaf
};
newNode->num_keys = M/2 - 1;
if (!child->is_leaf) {
for (int i = 0; i < M/2; i++) {
newNode->children[i] = child->children[i + M/2];
}
P a g e | 37
child->num_keys = M/2 - 1;
parent->children[index + 1] = newNode;
// Shift parent's keys to insert the middle key from the child
for (int i = parent->num_keys - 1; i >= index; i--) {
parent->keys[i + 1] = parent->keys[i];
}
if (node->is_leaf) {
// Insert key into the sorted order
while (i >= 0 && node->keys[i] > key) {
node->keys[i + 1] = node->keys[i];
i--;
}
node->keys[i + 1] = key;
node->num_keys++;
} else {
// Find the child to insert the key
while (i >= 0 && node->keys[i] > key) {
i--;
}
i++;
if (node->children[i]->num_keys == M - 1) {
// Split child if it's full
splitChild(node, i);
if (node == NULL) {
// Create a new root node
*root = createNode(true);
(*root)->keys[0] = key;
(*root)->num_keys = 1;
} else {
if (node->num_keys == M - 1) {
// Split the root if it's full
struct BTreeNode *new_root = createNode(false);
new_root->children[0] = node;
splitChild(new_root, 0);
*root = new_root;
}
insertNonFull(*root, key);
}
}
insert(&root, 10);
insert(&root, 20);
insert(&root, 5);
insert(&root, 6);
insert(&root, 12);
insert(&root, 30);
return 0;
}
Time Complexity:
Output:
Experiment no. 9
P a g e | 40
// Kruskal's algorithm in C
#include <stdio.h>
#define MAX 30
edge_list elist;
int Graph[MAX][MAX], n;
edge_list spanlist;
void kruskalAlgo();
int find(int belongs[], int vertexno);
void applyUnion(int belongs[], int c1, int c2);
void sort();
void print();
sort();
belongs[i] = i;
spanlist.n = 0;
if (cno1 != cno2) {
spanlist.data[spanlist.n] = elist.data[i];
spanlist.n = spanlist.n + 1;
applyUnion(belongs, cno1, cno2);
}
}
}
// Sorting algo
void sort() {
int i, j;
edge temp;
int main() {
int i, j, total_cost;
n = 6;
Graph[0][0] = 0;
Graph[0][1] = 4;
Graph[0][2] = 4;
Graph[0][3] = 0;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;
Graph[1][0] = 4;
Graph[1][1] = 0;
Graph[1][2] = 2;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 0;
Graph[1][6] = 0;
Graph[2][0] = 4;
Graph[2][1] = 2;
Graph[2][2] = 0;
Graph[2][3] = 3;
Graph[2][4] = 4;
Graph[2][5] = 0;
Graph[2][6] = 0;
Graph[3][0] = 0;
Graph[3][1] = 0;
Graph[3][2] = 3;
Graph[3][3] = 0;
Graph[3][4] = 3;
Graph[3][5] = 0;
Graph[3][6] = 0;
Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 4;
Graph[4][3] = 3;
Graph[4][4] = 0;
Graph[4][5] = 0;
Graph[4][6] = 0;
P a g e | 43
Graph[5][0] = 0;
Graph[5][1] = 0;
Graph[5][2] = 2;
Graph[5][3] = 0;
Graph[5][4] = 3;
Graph[5][5] = 0;
Graph[5][6] = 0;
kruskalAlgo();
print();
}
The time complexity of Kruskal's algorithm for finding the minimum spanning tree of a
graph is (O(ElogV)), where (E) is the number of edges in the graph and (V) is the number
of vertices: Sorting edges: This takes (O(ElogE)) time Union-find: This takes at most
(O(logV)) time for every edge (E).
Output:
Experiment no. 10
P a g e | 44
Given a bag with maximum weight capacity of W and a set of items, each having a
weight and a value associated with it. Decide the number of each item to take in a
collection such that the total weight is less than the capacity and the total value is
maximized.
// Driver code
int main()
{
int profit[] = { 60, 100, 120 };
int weight[] = { 10, 20, 30 };
int W = 50;
P a g e | 45
Output:
Time Complexity:
The time complexity of the knapsack algorithm is (O(N*W)), where (N) is the number of
weight elements and (W) is the capacity of the knapsack.
Experiment no. 11
P a g e | 46
The travelling salesman problem is a graph computational problem where the salesman
needs to visit all cities (represented using nodes in a graph) in a list just once and the
distances (represented using edges in the graph) between all these cities are known. The
solution that is needed to be found for this problem is the shortest possible route in
which the salesman visits all the cities and returns to the origin city.
#include <stdio.h>
int tsp_g[10][10] = {
{12, 30, 33, 10, 45},
{56, 22, 9, 15, 18},
{29, 13, 8, 5, 12},
{33, 28, 16, 10, 3},
{1, 4, 30, 24, 20}
};
int visited[10], n, cost = 0;
/* main function */
int main(){
int i, j;
n = 5;
for(i = 0; i < n; i++) {
visited[i] = 0;
}
printf("Shortest Path: ");
travellingsalesman(0);
printf("\nMinimum Cost: ");
printf("%d\n", cost);
return 0;
}
Output:
Experiment No. 12
P a g e | 48
Given a value of V Rs and an infinite supply of each of the denominations {1, 2, 5, 10, 20,
50, 100, 500, 1000} valued coins/notes, the task is to find the minimum number of coins
and/or notes needed to make the change?
int main(void)
{
// input value
int n = 93;
Output: