0% found this document useful (0 votes)
31 views46 pages

DSA (21EECF201) TermworkReport 1

This document contains a term-work report submitted by a student named SHYAM DESAI for their Data Structures Applications Lab course. The report explains different algorithm types including iterative, recursive, backtracking, divide and conquer, dynamic programming, greedy, branch and bound, brute force, and randomized algorithms. For each type, it provides two examples of programs that use different data structures and calculates their time complexities. It also includes fully coded solutions for examples of the divide and conquer and greedy algorithm types.

Uploaded by

Shyam Desai
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)
31 views46 pages

DSA (21EECF201) TermworkReport 1

This document contains a term-work report submitted by a student named SHYAM DESAI for their Data Structures Applications Lab course. The report explains different algorithm types including iterative, recursive, backtracking, divide and conquer, dynamic programming, greedy, branch and bound, brute force, and randomized algorithms. For each type, it provides two examples of programs that use different data structures and calculates their time complexities. It also includes fully coded solutions for examples of the divide and conquer and greedy algorithm types.

Uploaded by

Shyam Desai
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/ 46

KLE Technological University

School of Electronics and Communication Engineering

Data Structures Applications Lab (21EECF201) [0-0-2]


Term-work Report
Term-work 01
Student Name SHYAM DESAI
SRN 01FE21BEC110 Roll Number 307 Division C
Code of ethics:
I hereby declare that I am bound by ethics and have not copied any text/program/figure without
acknowledging the content creators. I abide to the rule that upon plagiarized content all my marks will be
made to zero.

Digital signature of the student


Apply Programming Identify Constraints Integrate Debugging Remarks Total
Skills and Implement Modules and Tool (20 Marks)
(5 marks) (10 marks) (3 Marks) usage
(2 marks)

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)

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

2 QUEUES AND STRUCTURES O(2n)


Brute force 1 2D ARRAY O(n!)
2 1D ARRAY O(2^n)
Randomized 1 ARRAY O(n*log(n))
2 ARRAY O(n)
Were you able to solve this problem? If not what where the challenges?

-YES

Modularity Documentation Indentation Programming practices

1.TYPE OF ALGORITHM: DIVIDE AND CONQUER

Details of the algorithm:


The Divide and Conquer algorithm is a problem-solving technique that involves breaking
down a problem into smaller sub-problems and solving them independently. The solutions
to these smaller sub-problems are then combined to obtain the solution to the original
problem. The idea behind this technique is to simplify complex problems by dividing them
into smaller pieces.
The 3 steps of the Divide and Conquer algorithm are:
1.Divide: The problem is divided into smaller sub-problems that are similar to the original
problem but of smaller size.
2.Conquer: The sub-problems are solved recursively using the same algorithm until they
become simple enough to be solved directly.
3.Combine: The solutions of the sub-problems are combined to solve the original problem.

examples of Divide and Conquer are


1. Binary Search
2. Merge Sort
3. Quick Sort
CODE FOR EXAMPLE 1: BINARY SEARCH
#include <stdio.h>
int binarySearch(int A[],int n,int key);
int main()
{
int A[50],n,key,index;
printf("Enter number of elements=");
scanf("%d",&n);
printf("Enter the elements in ascending order:\n");
for (int i=0;i<n;i++)
{
scanf("%d", &A[i]);
}
printf("Enter key to search=");

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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;
}

int binarySearch(int A[],int n,int key)


{
int l = 0,h = n - 1, mid;
while (l <= h) {
mid = (l + h) / 2;
if (key == A[mid])
return mid;
if (key < A[mid])
h = mid - 1;
else
l = mid + 1;
}
return -1;
}

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

Time complexity calculation:

O(logn)

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

CODE FOR EXAMPLE 2:MERGE SORT

#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]);
}

printf("Given array is:\n");


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

mergeSort(arr,0,n - 1);

printf("\nSorted array is:\n");


for (int i=0; i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
void merge(int arr[], int l, int m, int r)
{
int i,j,k;
int n1 = m-l+1;
int n2 = r-m;
int L[n1], R[n2];

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;

while (i < n1 && j < n2)


{

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

if (L[i] <= R[j])


{
arr[k] = L[i];
i++;
} else
{
arr[k] = R[j];
j++;
}
k++;
}

while (i < n1)


{
arr[k] = L[i];
i++;
k++;
}

while (j < n2)


{
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(int arr[], int l, int r)
{
if (l < r)
{
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}

Sample Input:

Enter number of elements in the array: 5

Enter elements of the array: 9

5,8,2,4,3

Sample Output:

Given array is:

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

9 5 8 2 43

Sorted array is:

2 5 8 9 43

Time complexity calculation:

O(nlogn)

Modularity Documentation Indentation Programming practices

2.TYPE OF ALGORITHM: GREEDY


Details of the algorithm:
A greedy algorithm is a type of problem-solving algorithm that makes the locally optimal
choice at each step in the hope of finding a global optimum. This means that the algorithm
selects the best option available at each stage of the problem, without considering the
long-term consequences or exploring all possible solutions.
Greedy algorithms are easy to implement and typically have less time complexity.
However, in many problems, a greedy strategy does not produce an optimal solution.

1.Define the problem and identify the set of possible solutions.


2.Determine the criterion for selecting the best option at each step.
3.Choose the locally optimal solution that satisfies the selection criterion.
4.Update the problem by removing the selected option or modifying the remaining
options.
5.Repeat steps 3 and 4 until the problem is solved or the desired outcome is achieved.
CODE FOR EXAMPLE 1: KNAPSACK PROBLEM
#include <stdio.h>
#include <stdlib.h>

int max(int a, int b) {


return (a > b)? a : b;
}

int knapSack(int W, int wt[], int val[], int n)


{
int i, w;
int K[n+1][W+1];

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


{

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

for (w = 0; w <= W; w++)


{
if (i==0 || w==0)
K[i][w] = 0;
else if (wt[i-1] <= w)
K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w]);
else
K[i][w] = K[i-1][w];
}
}

return K[n][W];
}

int main()
{
int n, W;

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


scanf("%d", &n);

int val[n], wt[n];

printf("Enter the weight and value of each item:\n");


for (int i = 0; i < n; i++) {
printf("Item %d:\n", i+1);
printf("Weight = ");
scanf("%d", &wt[i]);
printf("Value = ");
scanf("%d", &val[i]);
}

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


scanf("%d", &W);

printf("Maximum value that can be put in a knapsack of capacity %d is %d\n", W,


knapSack(W, wt, val, n));

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:

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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

Time complexity calculation:

O(nW), where n is the number of items and W is the maximum weight capacity of the knapsack

CODE FOR EXAMPLE 2: OPTIMAL MERGE PATTERN

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

#define MAX_SIZE 100

int min(int a, int b)


{
return a < b ? a : b;
}

int optimal_merge_pattern(int arr[], int n)


{
int i, j, k, cost = 0;
int temp[MAX_SIZE];
for (i = 0; i < n; i++)
{
temp[i] = arr[i];
}
while (n > 1)
{
i = j = k = 0;
while (i < n)
{
if (i + 1 < n && temp[i] > temp[i + 1])
{
j = i + 1;
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

if (j + 1 < n && temp[j] > temp[j + 1])


{
k = j + 1;
}
cost += temp[i] + temp[j] + temp[k];
temp[i] = temp[j] + temp[k];
i += 2;
j = k = 0;
}
n = i / 2;
}
return cost;
}

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:

Enter the number of arrays: 2

Enter the size of the arrays:

Sample Output:

The optimal merge pattern cost is: 6

Time complexity calculation:

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

O(n^2)

Modularity Documentation Indentation Programming practices

3.TYPE OF ALGORITHM: BRANCH AND BOUND


Details of the algorithm:
Branch and Bound is an algorithmic technique used in optimization problems to
systematically explore the space of possible solutions and find the optimal solution. It is
commonly used in problems such as integer programming, combinatorial optimization,
and graph problems

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;

void copyToFinal(int curr_path[])


{
for (int i=0; i<N; i++)
final_path[i] = curr_path[i];
final_path[N] = curr_path[0];
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

int firstMin(int adj[N][N], int i)


{
int min = INT_MAX;
for (int k=0; k<N; k++)
if (adj[i][k]<min && i != k)
min = adj[i][k];
return min;
}

int secondMin(int adj[N][N], int i)


{
int first = INT_MAX, second = INT_MAX;
for (int j=0; j<N; j++)
{
if (i == j)
continue;

if (adj[i][j] <= first)


{
second = first;
first = adj[i][j];
}
else if (adj[i][j] <= second &&
adj[i][j] != first)
second = adj[i][j];
}
return second;
}

void TSPRec(int adj[N][N], int curr_bound, int curr_weight,


int level, int curr_path[])
{
if (level==N)
{
if (adj[curr_path[level-1]][curr_path[0]] != 0)
{
int curr_res = curr_weight +
adj[curr_path[level-1]][curr_path[0]];

if (curr_res < final_res)


{
copyToFinal(curr_path);
final_res = curr_res;
}
}
return;
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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


{
if (adj[curr_path[level-1]][i] != 0 &&
visited[i] == false)
{
int temp = curr_bound;
curr_weight += adj[curr_path[level-1]][i];

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);

if (curr_bound + curr_weight < final_res)


{
curr_path[level] = i;
visited[i] = true;

TSPRec(adj, curr_bound, curr_weight, level+1,


curr_path);
}

curr_weight -= adj[curr_path[level-1]][i];
curr_bound = temp;

memset(visited, false, sizeof(visited));


for (int j=0; j<=level-1; j++)
visited[curr_path[j]] = true;
}
}
}

void TSP(int adj[N][N])


{
int curr_path[N+1];

int curr_bound = 0;
memset(curr_path, -1, sizeof(curr_path));
memset(visited, 0, sizeof(curr_path));

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


curr_bound += (firstMin(adj, i) +
secondMin(adj, i));

curr_bound = (curr_bound&1)? curr_bound/2 + 1 :


curr_bound/2;

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

visited[0] = true;
curr_path[0] = 0;

TSPRec(adj, curr_bound, 0, 1, curr_path);


}

int main()
{
int adj[N][N] = { {0, 10, 15, 20},
{10, 0, 35, 25},
{15, 35, 0, 30},
{20, 25, 30, 0}
};

TSP(adj);

printf("Minimum cost : %d\n", final_res);


printf("Path Taken : ");
for (int i=0; i<=N; i++)
printf("%d ", final_path[i]);

return 0;
}
Sample Input:
int adj[4][4] = { {0, 10, 15, 20},

{10, 0, 35, 25},

{15, 35, 0, 30},

{20, 25, 30, 0}

};
Sample Output:
Minimum cost : 80

Path Taken : 0 1 3 2 0

Time complexity calculation: O(n^2)

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

CODE FOR EXAMPLE 2:KNAPSACK USING BRANCH AND BOUND

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

typedef struct Item {


int value;
int weight;
double ratio;
} Item;

typedef struct KnapsackNode {


int *items;
int value;
int weight;
} KnapsackNode;

typedef struct Knapsack {


int maxWeight;
Item *items;
int n;
} Knapsack;

int cmpfunc(const void *a, const void *b) {


Item *ia = (Item *)a;
Item *ib = (Item *)b;
return ib->ratio - ia->ratio;
}

bool isPromising(KnapsackNode node, int maxWeight, int bestValue);


int getBound(KnapsackNode node, Item *items, int n, int maxWeight);

int solve(Knapsack knapsack) {


qsort(knapsack.items, knapsack.n, sizeof(Item), cmpfunc);

int bestValue = 0;

KnapsackNode queue[100000];
int front = 0;
int rear = 0;

queue[rear++] = (KnapsackNode){NULL, 0, 0};

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

while (front != rear) {


KnapsackNode node = queue[front++];
int i = node.items == NULL ? 0 : node.items[0];

if (i == knapsack.n) {
bestValue = node.value > bestValue ? node.value : bestValue;
} else {
Item item = knapsack.items[i];

KnapsackNode withItem = {NULL, node.value + item.value, node.weight +


item.weight};
if (isPromising(withItem, knapsack.maxWeight, bestValue)) {
withItem.items = (int*)malloc((i + 2) * sizeof(int));
withItem.items[0] = i + 1;
for (int j = 1; j <= i; j++) {
withItem.items[j] = node.items[j];
}
withItem.items[i + 1] = i;
queue[rear++] = withItem;
}

KnapsackNode withoutItem = {NULL, node.value, node.weight};


if (isPromising(withoutItem, knapsack.maxWeight, bestValue)) {
withoutItem.items = (int*)malloc((i + 2) * sizeof(int));
withoutItem.items[0] = i + 1;
for (int j = 1; j <= i; j++) {
withoutItem.items[j] = node.items[j];
}
queue[rear++] = withoutItem;
}
}

if (node.items != NULL) {
free(node.items);
}
}

return bestValue;
}

bool isPromising(KnapsackNode node, int maxWeight, int bestValue) {


return node.weight <= maxWeight && node.value > bestValue;
}

int getBound(KnapsackNode node, Item *items, int n, int maxWeight) {


int remainingWeight = maxWeight - node.weight;
int bound = node.value;

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

for (int i = node.items == NULL ? 0 : node.items[0]; i < n; i++) {


Item item = items[i];

if (remainingWeight >= item.weight) {


bound += item.value;
remainingWeight -= item.weight;
} else {
bound += remainingWeight * item.ratio;
break;
}
}

return bound;
}

int main() {
int n,maxWeight,i,j;

printf("Enter number of items: ");


scanf("%d", &n);

Item items[n];

printf("Enter the value and weight of each item:\n");


for(i=0;i<n;i++)
{
scanf("%d %d",&items[i].value,&items[i].weight);
items[i].ratio=(double)items[i].value/items[i].weight;
}

printf("Enter maximum weight: ");


scanf("%d", &maxWeight);

Knapsack knapsack={maxWeight, items,n};

printf("%d\n", solve(knapsack));
}

Sample Input:

Enter number of items: 3

Enter the value and weight of each item:

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

value=1

weight=2

value=3

weight=4

value=5

weight=6

Enter maximum weight: 6

Sample Output:

Time complexity calculation:

O(2n)

Modularity Documentation Indentation Programming practices

4.TYPE OF ALGORITHM: DYNAMIC PROGRAMMING


Details of the algorithm:

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

Dynamic Programming (DP) is a problem-solving technique used to solve complex


problems by breaking them down into simpler subproblems. It involves solving the
subproblems only once and storing their results in memory, so they can be used later to
solve larger problems

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>

// Function to find minimum number of scalar multiplications needed to multiply matrices


int MatrixChainOrder(int p[], int n)
{
int m[n][n];

// Cost is zero when multiplying one matrix.


for (int i = 1; i < n; i++)
m[i][i] = 0;

// 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()
{

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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]);

printf("Minimum number of scalar multiplications is %d ", MatrixChainOrder(p, n+1));

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

Time complexity calculation:

O(n^3)

CODE FOR EXAMPLE 2: ALL PAIRS SHORTEST PATH (FLOYD-WARSHALL)

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

#define INF INT_MAX

// Function to compute shortest distances between all pairs of vertices


void floydWarshall(int **graph, int V)
{
int dist[V][V];

// Initialize the distance matrix to the same values as the adjacency matrix
for (int i = 0; i < V; i++)
{

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

for (int j = 0; j < V; j++)


{
dist[i][j] = graph[i][j];
}
}

// Compute the shortest distances using dynamic programming


for (int k = 0; k < V; k++)
{
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}

// Print the shortest distances between all pairs of vertices


printf("Shortest distances between all pairs of vertices:\n");
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
if (dist[i][j] == INF)
printf("INF ");
else
printf("%d ", dist[i][j]);
}
printf("\n");
}
}

// Driver code
int main()
{
int V;
printf("Enter the number of vertices: ");
scanf("%d", &V);

// Dynamically allocate memory for the adjacency matrix


int **graph = (int**)malloc(V*sizeof(int*));
for (int i = 0; i < V; i++)
graph[i] = (int*)malloc(V*sizeof(int));

// Prompt the user to enter the adjacency matrix


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

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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


{
for (int j = 0; j < V; j++)
{
scanf("%d", &graph[i][j]);
if (graph[i][j] == -1)
graph[i][j] = INF;
}
}

// Compute the shortest distances between all pairs of vertices


floydWarshall(graph, V);

// Free dynamically allocated memory


for (int i = 0; i < V; i++)
free(graph[i]);
free(graph);

return 0;
}
Sample Input:

Enter the number of vertices: 2

Enter the adjacency matrix:

Sample Output:

Shortest distances between all pairs of vertices:

12

34

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

Time complexity calculation:

O(V^3), where V is the number of vertices in the graph

Modularity Documentation Indentation Programming practices

5.TYPE OF ALGORITHM: BACK TRACKING


Details of the algorithm:
Backtracking works by recursively trying different possibilities and undoing previous
choices as soon as it becomes clear that they cannot lead to a solution. It is especially

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

useful for solving combinatorial optimization problems, such as finding all possible
solutions to a Sudoku puzzle or the traveling salesman problem.

The process of backtracking involves three main steps:

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;

// Fill the rest of the table using bottom-up approach


for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= sum; j++)
{
// If the current element is greater than the current sum, ignore it
if (weights[i-1] > j)
dp[i][j] = dp[i-1][j];

// Otherwise, check if there's a subset with the remaining sum


else
dp[i][j] = dp[i-1][j] || dp[i-1][j-weights[i-1]];
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

// If there's a subset with the given sum, print it


if (dp[n][sum])
{
printf("Subset with sum %d: { ", sum);
int i = n, j = sum;
while (i > 0 && j > 0)
{
// If the current element is included in the solution, print it and move diagonally up-
left
if (dp[i-1][j-weights[i-1]])
{
printf("%d ", weights[i-1]);
j -= weights[i-1];
}

// Otherwise, move up
i--;
}
printf("}\n");
}

// Otherwise, print that no subset was found


else
printf("No subset with sum %d.\n", sum);
}

// 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]);

printf("Enter the target sum: ");


scanf("%d", &sum);

// Find a subset that adds up to the given sum


subsetSum(weights, n, sum);

return 0;
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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 }

Time complexity calculation:

O(n*sum), where n is the number of elements and sum is the target sum

CODE FOR EXAMPLE 2: N QUEENS PROBLEM USING BACKTRACKING ALGORITHM

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

#define N 10

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

int n;
int board[N][N];

// Function to check if a queen can be placed at a given row and column


bool isSafe(int row, int col)
{
// Check for queens in the same column
for (int i = 0; i < row; i++)
{
if (board[i][col])
return false;
}

// Check for queens in the upper left diagonal


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

// Check for queens in the upper right diagonal


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

// If there are no conflicts, the position is safe


return true;
}

// Function to solve the N Queens problem using Backtracking


bool solveNQueens(int row)
{
// Base case: All queens have been placed
if (row == n)
return true;

// Try placing a queen in each column of the current row


for (int col = 0; col < n; col++)
{
// Check if the current position is safe
if (isSafe(row, col))
{
// Place the queen at the current position
board[row][col] = 1;

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

// Recur to place the remaining queens


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

// Backtrack by removing the queen from the current position


board[row][col] = 0;
}
}

// If all positions in the current row have been tried and none worked, return false
return false;
}

// Function to print the solution


void printSolution()
{
printf("Solution for %d Queens:\n", n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
}

// Driver code
int main()
{
printf("Enter the number of Queens: ");
scanf("%d", &n);

// Initialize the board to all 0's


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

// Solve the N Queens problem using Backtracking


if (solveNQueens(0))
printSolution();
else
printf("No solution exists for %d Queens.\n", n);

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

return 0;
}
Sample Input:

Enter the number of Queens: 4

Sample Output:

Solution for 4 Queens:

0100

0001

1000

0010

Time complexity calculation:

O(N!), where N is the number of queens.

Modularity Documentation Indentation Programming practices

6.TYPE OF ALGORITHM: BRUTE FORCE


Details of the algorithm:
Brute force is a problem-solving technique in computer science and mathematics that
involves exhaustively checking all possible solutions to a problem. It is a simple and
straightforward approach that works by checking every possible solution until the correct
one is found.
Despite its limitations, brute force can be useful in solving certain types of problems,

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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;

void tsp(int curr_city, int visited_cities, int cost) {


// Base case: All cities have been visited
if (visited_cities == ((1 << n) - 1)) {
// Return to the starting city and update the minimum cost if the total cost is less than
the current minimum cost
if (dist[curr_city][0] != 0 && cost + dist[curr_city][0] < min_cost) {
min_cost = cost + dist[curr_city][0];
}
return;
}
// Check all unvisited cities
for (int i = 0; i < n; i++) {
if (!(visited_cities & (1 << i)) && dist[curr_city][i] != 0) {
// Mark the current city as visited
visited[i] = 1;
// Recur for the next city and update the visited cities and cost
tsp(i, visited_cities | (1 << i), cost + dist[curr_city][i]);
// Mark the current city as unvisited for backtracking
visited[i] = 0;
}
}
}

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]);
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

}
// 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

Time complexity calculation:

O(n!)

CODE FOR EXAMPLE 2: KNAPSACK PROBLEM USING BRUTE FORCE

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

int n, capacity, max_profit;


int weight[100], profit[100], knapsack[100];

// Function to calculate profit for the given set of items


void calculateProfit(int index, int cur_weight, int cur_profit)
{
// If all items are considered, return
if (index == n)
{
// If current profit is greater than maximum profit found so far
if (cur_profit > max_profit)
{

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

max_profit = cur_profit;

// Store the items in the knapsack


for (int i = 0; i < n; i++)
{
knapsack[i] = 0;
if (weight[i] <= cur_weight)
{
knapsack[i] = 1;
cur_weight -= weight[i];
}
}
}
return;
}

// Include the current item


if (cur_weight + weight[index] <= capacity)
{
calculateProfit(index+1, cur_weight+weight[index], cur_profit+profit[index]);
}

// Exclude the current item


calculateProfit(index+1, cur_weight, cur_profit);
}

// Function to print the solution


void printSolution()
{
printf("Maximum profit: %d\n", max_profit);
printf("Items in the knapsack:\n");
for (int i = 0; i < n; i++)
{
if (knapsack[i])
printf("%d ", i+1);
}
printf("\n");
}

// Driver code
int main()
{
printf("Enter the number of items: ");
scanf("%d", &n);

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


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

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

scanf("%d", &weight[i]);
}

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


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

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


scanf("%d", &capacity);

calculateProfit(0, 0, 0);

printSolution();

return 0;
}
Sample Input:

Enter the number of items: 2

Enter the weights of the items: 1

Enter the profits of the items: 3

Enter the capacity of the knapsack: 6

Sample Output:

Maximum profit: 7

Items in the knapsack:

12

Time complexity calculation:

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

O(2^n), where n is the number of items

Modularity Documentation Indentation Programming practices

7.TYPE OF ALGORITHM: RANDOMIZED


Details of the algorithm:
A randomized algorithm is an algorithm that uses a random number generator to
introduce randomness in its execution. In other words, it is an algorithm that makes use of
random choices or inputs to solve a problem
There are two types of randomized algorithms: Las Vegas algorithms and Monte Carlo
algorithms. Las Vegas algorithms always produce the correct solution to a problem but
may take different amounts of time to do so. Monte Carlo algorithms always produce a
solution to a problem, but it may not always be the correct solution.
Randomized algorithms have several advantages over deterministic algorithms. They are
often simpler, faster, and require less memory. They can also be used to solve problems
that are intractable using deterministic algorithms.
CODE FOR EXAMPLE 1: QUICK SORT ALGORITHM USING RANDOMIZED ALGORITHM
#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;

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

*b = temp;
}

// Function to generate a random number in the given range


int randInRange(int low, int high)
{
return rand() % (high - low + 1) + low;
}

// Function to partition the array using the last element as pivot


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

for (int j = low; j <= high - 1; j++)


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

swap(&arr[i + 1], &arr[high]);


return i + 1;
}

// Randomized quicksort function


void randomizedQuickSort(int arr[], int low, int high)
{
if (low < high)
{
int pivotIndex = randInRange(low, high);
swap(&arr[pivotIndex], &arr[high]);
int pivot = partition(arr, low, high);
randomizedQuickSort(arr, low, pivot - 1);
randomizedQuickSort(arr, pivot + 1, high);
}
}

// Function to print the array


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

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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]);
}

srand(time(NULL)); // Seed for random number generator


randomizedQuickSort(arr, 0, n - 1);

printf("Sorted array: ");


printArray(arr, n);

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

Time complexity calculation:

O(n*log(n))

CODE FOR EXAMPLE 2: FISHER-YATES SHUFFLE

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

void swap(int *a, int *b) {


int temp = *a;
*a = *b;
*b = temp;
}

void fisher_yates_shuffle(int arr[], int n) {


srand(time(NULL)); // seed the random number generator
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1);
swap(&arr[i], &arr[j]);
}
}

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);

printf("Shuffled array: ");


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

return 0;
}
Sample Input:

Enter the size of the array: 4

Enter 4 integers: 1

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

Sample Output:

Shuffled array: 1 3 4 2

Time complexity calculation:

O(n)

Modularity Documentation Indentation Programming practices

8.TYPE OF ALGORITHM: ITERATIVE


Details of the algorithm:
An iterative algorithm is an algorithmic approach that repeatedly executes a set of
instructions, each time with the goal of getting closer to the desired result. It is a process
of repeatedly applying a fixed set of rules or procedures to get the desired output.
Iterative algorithms can be implemented using different programming paradigms, such as
procedural programming, object-oriented programming, and functional programming.
They can also be implemented using different control structures, such as loops, recursion,
and iteration.

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>

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

// Function to swap two elements


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

// Selection sort function


void selectionSort(int arr[], int n)
{
for (int i = 0; i < n - 1; i++)
{
int min_idx = i;

// 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]);
}
}

// Function to print the array


void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
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: ");

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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


{
scanf("%d", &arr[i]);
}

selectionSort(arr, n);

printf("Sorted array: ");


printArray(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

Time complexity calculation:

O(n^2)

CODE FOR EXAMPLE 2: ITERATIVE QUICK SORT

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

#define MAX_STACK_SIZE 100

// Function to swap two elements


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

// Function to partition the array and return the pivot index

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

int partition(int arr[], int low, int high)


{
int pivot = arr[high];
int i = low - 1;

for (int j = low; j <= high - 1; j++)


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

swap(&arr[i + 1], &arr[high]);


return i + 1;
}

// Iterative quick sort function


void quickSortIterative(int arr[], int low, int high)
{
// Create a stack to keep track of partitions that still need to be sorted
int stack[MAX_STACK_SIZE];
int top = -1;

// Push initial values of low and high to the stack


stack[++top] = low;
stack[++top] = high;

while (top >= 0)


{
// Pop low and high values from the stack
high = stack[top--];
low = stack[top--];

// Partition the array and get the pivot index


int pivot = partition(arr, low, high);

// 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)
{

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

stack[++top] = pivot + 1;
stack[++top] = high;
}
}
}

// Function to print the array


void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
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]);
}

quickSortIterative(arr, 0, n - 1);

printf("Sorted array: ");


printArray(arr, n);

return 0;
}
Sample Input:

Enter the size of the array: 4

Enter the elements of the array: 9

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

Sample Output:

Sorted array: 2 3 5 9

Time complexity calculation:

O(n log n)

Modularity Documentation Indentation Programming practices

9.TYPE OF ALGORITHM: RECURSIVE


Details of the algorithm:
A recursive algorithm is an algorithm that solves a problem by calling itself with a smaller
instance of the same problem. It is a function that calls itself one or more times with
different input parameters until a specific base condition is met.

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>

// Recursive binary search function


int binarySearch(int arr[], int low, int high, int key)
{
if (low <= high)
{
int mid = low + (high - low) / 2;

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

// If the key is present at the middle itself


if (arr[mid] == key)
{
return mid;
}

// 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);
}

// Else the key can only be present in the right subarray


return binarySearch(arr, mid + 1, high, key);
}

// If the key is not present in the array


return -1;
}

// 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]);
}

printf("Enter the key to be searched: ");


scanf("%d", &key);

int result = binarySearch(arr, 0, n - 1, key);


if (result == -1)
{
printf("Key not found in the array.\n");
}
else
{
printf("Key found at index %d.\n", result);
}

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

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.

Time complexity calculation:

O(log n)

CODE FOR EXAMPLE 2: FINDING THE MAXIMUM OR MINIMUM ELEMENT IN AN ARRAY

#include <stdio.h>
#include <limits.h>

#define MAX_SIZE 100

// Recursive function to find maximum element in an array


int findMax(int arr[], int size)
{
// Base case: if array contains only one element
if (size == 1)
{
return arr[0];
}

// Find maximum element in the rest of the array


int max = findMax(arr, size - 1);

// Compare the maximum with the last element

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

if (arr[size - 1] > max)


{
max = arr[size - 1];
}

return max;
}

// Recursive function to find minimum element in an array


int findMin(int arr[], int size)
{
// Base case: if array contains only one element
if (size == 1)
{
return arr[0];
}

// Find minimum element in the rest of the array


int min = findMin(arr, size - 1);

// Compare the minimum with the last element


if (arr[size - 1] < min)
{
min = arr[size - 1];
}

return min;
}

// Driver code
int main()
{
int arr[MAX_SIZE], size;

// Get the size of the array from user


printf("Enter the size of the array (maximum %d): ", MAX_SIZE);
scanf("%d", &size);

// Get the elements of the array from user


printf("Enter the elements of the array: ");
for (int i = 0; i < size; i++)
{
scanf("%d", &arr[i]);
}

// Find the maximum and minimum element in the array


int max = findMax(arr, size);
int min = findMin(arr, size);

School of Electronics and Communication Engineering, KLE Technological University


KLE Technological University
School of Electronics and Communication Engineering

// Print the maximum and minimum element


printf("Maximum element in the array: %d\n", max);
printf("Minimum element in the array: %d\n", min);

return 0;
}
Sample Input:

Enter the size of the array (maximum 100): 4

Enter the elements of the array: 8

Sample Output:

Maximum element in the array: 8

Minimum element in the array: 1

Time complexity calculation:

O(n)

School of Electronics and Communication Engineering, KLE Technological University

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy