DSA (21EECF201) TermworkReport 1
DSA (21EECF201) TermworkReport 1
Problem Statement
Explain the operation of each algorithm type, take into account two examples of programmes for each
algorithm type, and express the time complexity of each programme.
1. Iterative, 2. Recursive, 3. Back tracking, 4. Divide and conquer, 5. Dynamic programming,
6. Greedy, 7. Branch and Bound, 8. Brute force, 9. Randomized
Type of algorithm Example Which data structures are used? What is the time
No complexity? O(n)
Iterative 1 ARRAY O(n^2)
2 STACK O(n log n)
Recursive 1 ARRAY O(log n)
2 ARRAY O(n)
Back tracking 1 2D ARRAY O(n*sum),
2 2D ARRAY O(N!), N is the number
of queens
Divide and conquer 1 1D ARRAY O(logn)
2 1D ARRAY O(nlogn)
Dynamic 1 2D ARRAY O(n^3)
programming
2 2D ARRAY O(V^3), V is the number of
vertices in the graph
Greedy 1 2D ARRAY O(nW), W is the maximum
weight capacity of the
knapsack
2 ARRAY O(n^2)
Branch and bound 1 2D ARRAY O(n^2)
-YES
scanf("%d",&key);
index = binarySearch(A,n,key);
if (index==-1)
printf("Element not found\n");
else
printf("Element found at index %d\n", index);
return 0;
}
Sample Input:
Enter number of elements=5
Enter the elements in ascending order:
1
2
3
6
7
Enter key to search=6
Sample Output:
Element found at index 3
O(logn)
#include <stdio.h>
void merge(int arr[], int l, int m, int r);
void mergeSort(int arr[], int l, int r);
int main()
{
int n, arr[50];
printf("Enter number of elements in the array: ");
scanf("%d", &n);
printf("Enter elements of the array: ");
for (int i = 0; i < n; i++)
{
scanf("%d",&arr[i]);
}
mergeSort(arr,0,n - 1);
for (i=0;i<n1;i++)
L[i]=arr[l+i];
for (j =0;j<n2;j++)
R[j]=arr[m+1+j];
i = 0;
j = 0;
k = l;
Sample Input:
5,8,2,4,3
Sample Output:
9 5 8 2 43
2 5 8 9 43
O(nlogn)
return K[n][W];
}
int main()
{
int n, W;
return 0;
}
Sample Input:
Enter the number of items: 3
Enter the weight and value of each item:
Item 1:
Weight = 1
Value = 2
Item 2:
Weight = 3
Value = 4
Item 3:
Weight = 5
Value = 6
Enter the maximum weight capacity of the knapsack: 5
Sample Output:
Maximum value that can be put in a knapsack of capacity 5 is 6
O(nW), where n is the number of items and W is the maximum weight capacity of the knapsack
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
int arr[MAX_SIZE];
printf("Enter the number of arrays: ");
scanf("%d", &n);
printf("Enter the size of the arrays:\n");
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
printf("The optimal merge pattern cost is: %d\n", optimal_merge_pattern(arr, n));
return 0;
}
Sample Input:
Sample Output:
O(n^2)
Branching: The node with the smallest lower bound is selected, and it is divided into two
or more subproblems. Each subproblem is obtained by assigning a value to one of the
decision variables of the original problem. The number of subproblems depends on the
branching rule used.
Bounding: Each subproblem is solved to obtain a lower bound on its optimal value. If the
lower bound is worse than the current best solution, the subproblem is discarded.
Otherwise, the subproblem is retained and added to the list of nodes to be explored.
CODE FOR EXAMPLE 1: TRAVELING SALESMAN PROBLEM
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#define N 4
int final_path[N+1];
bool visited[N];
int final_res = INT_MAX;
if (level==1)
curr_bound -= ((firstMin(adj, curr_path[level-1]) +
firstMin(adj, i))/2);
else
curr_bound -= ((secondMin(adj, curr_path[level-1]) +
firstMin(adj, i))/2);
curr_weight -= adj[curr_path[level-1]][i];
curr_bound = temp;
int curr_bound = 0;
memset(curr_path, -1, sizeof(curr_path));
memset(visited, 0, sizeof(curr_path));
visited[0] = true;
curr_path[0] = 0;
int main()
{
int adj[N][N] = { {0, 10, 15, 20},
{10, 0, 35, 25},
{15, 35, 0, 30},
{20, 25, 30, 0}
};
TSP(adj);
return 0;
}
Sample Input:
int adj[4][4] = { {0, 10, 15, 20},
};
Sample Output:
Minimum cost : 80
Path Taken : 0 1 3 2 0
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int bestValue = 0;
KnapsackNode queue[100000];
int front = 0;
int rear = 0;
if (i == knapsack.n) {
bestValue = node.value > bestValue ? node.value : bestValue;
} else {
Item item = knapsack.items[i];
if (node.items != NULL) {
free(node.items);
}
}
return bestValue;
}
return bound;
}
int main() {
int n,maxWeight,i,j;
Item items[n];
printf("%d\n", solve(knapsack));
}
Sample Input:
value=1
weight=2
value=3
weight=4
value=5
weight=6
Sample Output:
O(2n)
1)Overlapping subproblems: The problem can be broken down into subproblems, and the
same subproblem is called multiple times in the solution.
2)Optimal substructure: The solution to the problem can be constructed by combining the
solutions to its subproblems.
CODE FOR EXAMPLE 1: MATRIX CHAIN MULTIPLICATION USING DYNAMIC ROGRAMING
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
// L is chain length.
for (int L = 2; L < n; L++)
{
for (int i = 1; i < n-L+1; i++)
{
int j = i+L-1;
m[i][j] = INT_MAX;
for (int k = i; k <= j-1; k++)
{
// q = cost/scalar multiplications
int q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if (q < m[i][j])
m[i][j] = q;
}
}
}
return m[1][n-1];
}
// Driver code
int main()
{
int n;
printf("Enter the number of matrices: ");
scanf("%d", &n);
int *p = (int*)malloc((n+1)*sizeof(int));
printf("Enter the dimensions of matrices: ");
for (int i = 0; i <= n; i++)
scanf("%d", &p[i]);
free(p);
return 0;
}
Sample Input:
Enter the number of matrices: 2
Enter the dimensions of matrices: 1
2
3
Sample Output:
Minimum number of scalar multiplications is 6
O(n^3)
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
// Initialize the distance matrix to the same values as the adjacency matrix
for (int i = 0; i < V; i++)
{
// Driver code
int main()
{
int V;
printf("Enter the number of vertices: ");
scanf("%d", &V);
return 0;
}
Sample Input:
Sample Output:
12
34
useful for solving combinatorial optimization problems, such as finding all possible
solutions to a Sudoku puzzle or the traveling salesman problem.
1.Choosing: In this step, the function selects the next candidate to the solution. This
involves making a choice from a set of possible choices.
2.Checking: In this step, the function checks whether the current candidate satisfies the
problem's constraints. If it does, the function moves on to the next candidate, otherwise,
it backtracks to the previous candidate.
3.Backtracking: In this step, the function undoes the previous choice and selects a different
candidate. This involves moving back up the recursion stack and trying a different path.
CODE FOR EXAMPLE 1: SUBSET SUM PROBLEM
#include <stdio.h>
#include <stdbool.h>
#define MAX 10
// Function to find subsets that add up to the given sum using dynamic programming
void subsetSum(int weights[], int n, int sum)
{
// Create a 2D array to store the solutions to subproblems
bool dp[n+1][sum+1];
// Initialize the first column to true (there's always a subset with sum 0)
for (int i = 0; i <= n; i++)
dp[i][0] = true;
// Initialize the first row (except dp[0][0]) to false (no subset with non-zero sum)
for (int j = 1; j <= sum; j++)
dp[0][j] = false;
// Otherwise, move up
i--;
}
printf("}\n");
}
// Driver code
int main()
{
int n, sum;
printf("Enter the number of elements: ");
scanf("%d", &n);
int weights[MAX];
printf("Enter the elements: ");
for (int i = 0; i < n; i++)
scanf("%d", &weights[i]);
return 0;
}
Sample Input:
Enter the number of elements: 2
Enter the elements: 1
2
Enter the target sum: 3
Sample Output:
Subset with sum 3: { 2 1 }
O(n*sum), where n is the number of elements and sum is the target sum
#include <stdio.h>
#include <stdbool.h>
#define N 10
int n;
int board[N][N];
// If all positions in the current row have been tried and none worked, return false
return false;
}
// Driver code
int main()
{
printf("Enter the number of Queens: ");
scanf("%d", &n);
return 0;
}
Sample Input:
Sample Output:
0100
0001
1000
0010
particularly those with a small number of possible solutions. It is also a useful tool for
verifying the correctness of more complex algorithms and can be used as a baseline for
comparison when evaluating the performance of more sophisticated techniques
CODE FOR EXAMPLE 1: TRAVELLING SALESMAN PROBLEM USING BRUTE FORCE
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_N 10
int n;
int dist[MAX_N][MAX_N];
int visited[MAX_N];
int min_cost = INT_MAX;
int main() {
// Get input from the user
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]);
}
}
// Initialize the visited array
for (int i = 0; i < n; i++) {
visited[i] = 0;
}
// Start the TSP from the first city
visited[0] = 1;
tsp(0, 1, 0);
// Print the minimum cost
printf("Minimum cost: %d\n", min_cost);
return 0;
}
Sample Input:
Enter the number of cities: 2
Enter the distance matrix:
1
2
3
4
Sample Output:
Minimum cost: 5
O(n!)
#include <stdio.h>
#include <stdlib.h>
max_profit = cur_profit;
// Driver code
int main()
{
printf("Enter the number of items: ");
scanf("%d", &n);
scanf("%d", &weight[i]);
}
calculateProfit(0, 0, 0);
printSolution();
return 0;
}
Sample Input:
Sample Output:
Maximum profit: 7
12
*b = temp;
}
printf("\n");
}
// Driver code
int main()
{
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter the elements of the array: ");
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
return 0;
}
Sample Input:
Enter the size of the array: 4
Enter the elements of the array: 8
6
2
5
Sample Output:
Sorted array: 2 5 6 8
O(n*log(n))
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter %d integers: ", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
fisher_yates_shuffle(arr, n);
return 0;
}
Sample Input:
Enter 4 integers: 1
Sample Output:
Shuffled array: 1 3 4 2
O(n)
The advantages of iterative algorithms include their flexibility, efficiency, and scalability.
They can handle large datasets and complex computations and can be easily modified or
extended to meet changing requirements.
CODE FOR EXAMPLE 1: SELECTION SORT USING ITERATIVE ALGORITHM
#include <stdio.h>
// Find the index of minimum element in the unsorted part of the array
for (int j = i + 1; j < n; j++)
{
if (arr[j] < arr[min_idx])
{
min_idx = j;
}
}
// Swap the minimum element with the first element of the unsorted part
swap(&arr[min_idx], &arr[i]);
}
}
// Driver code
int main()
{
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter the elements of the array: ");
selectionSort(arr, n);
return 0;
}
Sample Input:
Enter the size of the array: 4
Enter the elements of the array: 9
2
5
3
Sample Output:
Sorted array: 2 3 5 9
O(n^2)
#include <stdio.h>
#include <stdlib.h>
// If there are elements on the left of the pivot, push them to the stack
if (pivot - 1 > low)
{
stack[++top] = low;
stack[++top] = pivot - 1;
}
// If there are elements on the right of the pivot, push them to the stack
if (pivot + 1 < high)
{
stack[++top] = pivot + 1;
stack[++top] = high;
}
}
}
// Driver code
int main()
{
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter the elements of the array: ");
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
quickSortIterative(arr, 0, n - 1);
return 0;
}
Sample Input:
Sample Output:
Sorted array: 2 3 5 9
O(n log n)
The general structure of a recursive algorithm includes two parts: base case and recursive
case. Examples of problems that can be solved using recursive algorithms include
computing factorials, traversing a tree or graph, searching or sorting a list, and computing
Fibonacci numbers.
CODE FOR EXAMPLE 1: BINARY SEARCH USING A RECURSIVE ALGORITHM
#include <stdio.h>
// If key is smaller than mid, then it can only be present in the left subarray
if (arr[mid] > key)
{
return binarySearch(arr, low, mid - 1, key);
}
// Driver code
int main()
{
int n, key;
printf("Enter the size of the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter the elements of the array in sorted order: ");
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
return 0;
}
Sample Input:
Enter the size of the array: 4
Enter the elements of the array in sorted order: 5
6
7
8
Enter the key to be searched: 6
Sample Output:
Key found at index 1.
O(log n)
#include <stdio.h>
#include <limits.h>
return max;
}
return min;
}
// Driver code
int main()
{
int arr[MAX_SIZE], size;
return 0;
}
Sample Input:
Sample Output:
O(n)