0% found this document useful (0 votes)
3 views27 pages

Practical file part 2-compressed

The document outlines various algorithms including Linear Search, Binary Search, Matrix Chain Multiplication, Longest Common Subsequence, Optimal Binary Search Tree, Huffman Coding, Dijkstra's Algorithm, and Bellman-Ford Algorithm, along with their time complexities. It provides code implementations for each algorithm and summarizes their respective time complexities, such as O(N) for Linear Search, O(n^3) for Matrix Chain Multiplication, O(M*N) for Longest Common Subsequence, and O(VE) for Bellman-Ford. Additionally, it mentions the complexities for Huffman Coding (O(N log N)), Dijkstra's Algorithm (O(V^2)), and DFS/BFS (O(V+E)).

Uploaded by

Ashutosh Kewat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views27 pages

Practical file part 2-compressed

The document outlines various algorithms including Linear Search, Binary Search, Matrix Chain Multiplication, Longest Common Subsequence, Optimal Binary Search Tree, Huffman Coding, Dijkstra's Algorithm, and Bellman-Ford Algorithm, along with their time complexities. It provides code implementations for each algorithm and summarizes their respective time complexities, such as O(N) for Linear Search, O(n^3) for Matrix Chain Multiplication, O(M*N) for Longest Common Subsequence, and O(VE) for Bellman-Ford. Additionally, it mentions the complexities for Huffman Coding (O(N log N)), Dijkstra's Algorithm (O(V^2)), and DFS/BFS (O(V+E)).

Uploaded by

Ashutosh Kewat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Output-

TIME COMPLEXITY:
• TIME COMPLEXITY OF LINEAR SEARCH - O(N)
• Binary search has time complexity O(log n).
3 WAP to implement Matrix Chain Multiplication and analyze its complexity

Code-
#include <iostream>
#include <limits.h>

using namespace std;

// Matrix Ai has dimension p[i-1] x p[i] for i =


1..n

int MatrixChainMultiplication(int p[], int n)


{
int m[n][n];
int i, j, k, L, q;
for (i = 1; i < n; i++)
m[i][i] = 0; //number of multiplications are
0(zero) when there is only one matrix

//Here L is chain length. It varies from length


2 to length n.
for (L = 2; L < n; L++)
{
for (i = 1; i < n - L + 1; i++)
{
j = i + L - 1;
m[i][j] = INT_MAX; //assigning to
maximum value

for (k = i; k <= j - 1; k++)


{
q = m[i][k] + m[k + 1][j] + p[i - 1]
* p[k] * p[j];
if (q < m[i][j])
{
m[i][j] = q; //if number of
multiplications found less that number will be
updated.
}
}
}
}
return m[1][n - 1]; //returning the final answer
which is M[1][n]
}

int main()
{
int n, i;
cout << "Enter number of matrices\n";
cin >> n;

n++;

int arr[n];

cout << "Enter dimensions \n";

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


{
cout << "Enter d" << i << " :: ";
cin >> arr[i];
}

int size = sizeof(arr) / sizeof(arr[0]);

cout<<"Minimum number of multiplications is


"<<MatrixChainMultiplication(arr, size);

return 0;
}
Output-

The time complexity of the above top-down solution is O(n3) and requires O(n2)
extra space, where n is the total number of matrices.
4, WAP to implement Longest Common Subsequence Problem and
analyze its time complexity.

Code-
Output-

TIME COMPLEXITY: TIME COMPLEXITY OF LONGEST COMMON SUBSEQUENCE


PROBLEM O(M * N)
5, WAP to implement Optimal Binary Search Tree Problem and analyze its time
complexity

Code-
Output-

TIME COMPLEXITY OF OPTIMAL BINARY SEARCH TREE PROBLEM O(LOG N).


6, WAP to implement Huffman coding and analyze its time complexity

Code-
#include <stdio.h>
#include <stdlib.h>
#define MAX_TREE_HT 100
struct MinHeapNode
{
char data;
unsigned freq;
struct MinHeapNode *left, *right;
};
struct MinHeap
{
unsigned size;
unsigned capacity;
struct MinHeapNode **array;
};
struct MinHeapNode *newNode(char data, unsigned
freq)
{
struct MinHeapNode *temp = (struct MinHeapNode
*)malloc(
sizeof(struct MinHeapNode));
temp->left = temp->right = NULL;
temp->data = data;
temp->freq = freq;
return temp;
}
struct MinHeap *createMinHeap(unsigned capacity)
{
struct MinHeap *minHeap = (struct MinHeap
*)malloc(sizeof(struct MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (struct MinHeapNode **)malloc(
minHeap->capacity * sizeof(struct
MinHeapNode *));
return minHeap;
}
void swapMinHeapNode(struct MinHeapNode **a,
struct MinHeapNode **b)
{
struct MinHeapNode *t = *a;
*a = *b;
*b = t;
}
void minHeapify(struct MinHeap *minHeap, int idx)
{
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < minHeap->size && minHeap-
>array[left]->freq < minHeap->array[smallest]->freq)
smallest = left;
if (right < minHeap->size && minHeap-
>array[right]->freq < minHeap->array[smallest]-
>freq)
smallest = right;
if (smallest != idx)
{
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
int isSizeOne(struct MinHeap *minHeap)
{
return (minHeap->size == 1);
}
struct MinHeapNode *extractMin(struct MinHeap
*minHeap)
{
struct MinHeapNode *temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size
- 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
void insertMinHeap(struct MinHeap *minHeap,
struct MinHeapNode *minHeapNode)
{
++minHeap->size;
int i = minHeap->size - 1;
while (i && minHeapNode->freq < minHeap-
>array[(i - 1) / 2]->freq)
{
minHeap->array[i] = minHeap->array[(i - 1) /
2];
i = (i - 1) / 2;
}
minHeap->array[i] = minHeapNode;
}
void buildMinHeap(struct MinHeap *minHeap)
{
int n = minHeap->size - 1;
int i;
for (i = (n - 1) / 2; i >= 0; --i)
minHeapify(minHeap, i);
}
void printArr(int arr[], int n)
{
int i;
for (i = 0; i < n; ++i)
printf("%d", arr[i]);
printf("\n");
}
int isLeaf(struct MinHeapNode *root)
{
return !(root->left) && !(root->right);
}
struct MinHeap *createAndBuildMinHeap(char data[],
int freq[],
int size)
{
struct MinHeap *minHeap = createMinHeap(size);
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(data[i],
freq[i]);
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
struct MinHeapNode *buildHuffmanTree(char data[],
int freq[], int
size)
{
struct MinHeapNode *left, *right, *top;
struct MinHeap *minHeap =
createAndBuildMinHeap(data, freq, size);
while (!isSizeOne(minHeap))
{
left = extractMin(minHeap);
right = extractMin(minHeap);
top = newNode('$', left->freq + right-
>freq);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
void printCodes(struct MinHeapNode *root, int arr[],
int top)
{
if (root->left)
{
arr[top] = 0;
printCodes(root->left, arr, top + 1);
}
if (root->right)
{
arr[top] = 1;
printCodes(root->right, arr, top + 1);
}
if (isLeaf(root))
{
printf("%c: ", root->data);
printArr(arr, top);
}
}
void HuffmanCodes(char data[], int freq[], int size)
{
struct MinHeapNode *root =
buildHuffmanTree(data, freq, size);
int arr[MAX_TREE_HT], top = 0;
printCodes(root, arr, top);
}
int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
int freq[] = {5, 9, 12, 13, 16, 45};
int size = sizeof(arr) / sizeof(arr[0]);
HuffmanCodes(arr, freq, size);
return 0;
}
Output-

THE TIME COMPLEXITY OF THE HUFFMAN ALGORITHM IS O(NLOGN)

7, WAP to implement Dijkstra’s Algorithm and analyze its complexity.

Code-
#include <stdio.h>
#include <conio.h>
#define INFINITY 9999
#define MAX 10
void dijkstra(int G[MAX][MAX], int n, int
startnode);
int main()
{
int G[MAX][MAX], i, j, n, u;
printf("Enter no. of vertices:");
scanf("%d", &n);
printf("\nEnter the adjacency matrix:\n");
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &G[i][j]);
printf("\nEnter the starting node:");
scanf("%d", &u);
dijkstra(G, n, u);
return 0;
}
void dijkstra(int G[MAX][MAX], int n, int startnode)
{
int cost[MAX][MAX], distance[MAX], pred[MAX];
int visited[MAX], count, mindistance, nextnode,
i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (G[i][j] == 0)
cost[i][j] = INFINITY;
else
cost[i][j] = G[i][j];
for (i = 0; i < n; i++)
{
distance[i] = cost[startnode][i];
pred[i] = startnode;
visited[i] = 0;
}
distance[startnode] = 0;
visited[startnode] = 1;
count = 1;
while (count < n - 1)
{
mindistance = INFINITY;
for (i = 0; i < n; i++)
if (distance[i] < mindistance &&
!visited[i])
{
mindistance = distance[i];
nextnode = i;
}
visited[nextnode] = 1;
for (i = 0; i < n; i++)
if (!visited[i])
if (mindistance + cost[nextnode][i]
< distance[i])
{
distance[i] = mindistance +
cost[nextnode][i];
pred[i] = nextnode;
}
count++;
}
for (i = 0; i < n; i++)
if (i != startnode)
{
printf("\nDistance of node %d = %d\n",
i, distance[i]);
printf("\nPath=%d ", i);
j = i;
do
{
j = pred[j];
printf("<-%d", j);
} while (j != startnode);
}
}

Output-

TIME COMPLEXITY OF DIJKSTRA'S ALGORITHM IS O ( V 2 )


8, WAP to implement Bellmen Ford Algorithm and analyze its time complexity

Code-
#include <bits/stdc++.h>
struct Edge
{
int src, dest, weight;
};
struct Graph
{
int V, E;
struct Edge *edge;
};
struct Graph *createGraph(int V, int E)
{
struct Graph *graph = new Graph;
graph->V = V;
graph->E = E;
graph->edge = new Edge[E];
return graph;
}
void printArr(int dist[], int n)
{
printf("Vertex Distance from Source\n");
for (int i = 0; i < n; ++i)
printf("%d \t\t %d\n", i, dist[i]);
}
void BellmanFord(struct Graph *graph, int src)
{
int V = graph->V;
int E = graph->E;
int dist[V];
for (int i = 0; i < V; i++)
dist[i] = INT_MAX;
dist[src] = 0;
for (int i = 1; i <= V - 1; i++)
{
for (int j = 0; j < E; j++)
{
int u = graph->edge[j].src;
int v = graph->edge[j].dest;
int weight = graph->edge[j].weight;
if (dist[u] != INT_MAX && dist[u] +
weight < dist[v])
dist[v] = dist[u] + weight;
}
}
for (int i = 0; i < E; i++)
{
int u = graph->edge[i].src;
int v = graph->edge[i].dest;
int weight = graph->edge[i].weight;
if (dist[u] != INT_MAX && dist[u] + weight <
dist[v])
{
printf("Graph contains negative weight
cycle");
return;
}
}
printArr(dist, V);
return;
}
int main()
{
int V = 5; // Number of vertices in graph
int E = 8; // Number of edges in graph
struct Graph *graph = createGraph(V, E);
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[0].weight = -1;
graph->edge[1].src = 0;
graph->edge[1].dest = 2;
graph->edge[1].weight = 4;
graph->edge[2].src = 1;
graph->edge[2].dest = 2;
graph->edge[2].weight = 3;
graph->edge[3].src = 1;
graph->edge[3].dest = 3;
graph->edge[3].weight = 2;
graph->edge[4].src = 1;
graph->edge[4].dest = 4;
graph->edge[4].weight = 2;
graph->edge[5].src = 3;
graph->edge[5].dest = 2;
graph->edge[5].weight = 5;
graph->edge[6].src = 3;
graph->edge[6].dest = 1;
graph->edge[6].weight = 1;
graph->edge[7].src = 4;
graph->edge[7].dest = 3;
graph->edge[7].weight = -3;
BellmanFord(graph, 0);
return 0;
}

Output-

TIME COMPLEXITY:
• WORST CASE TIME COMPLEXITY: Θ(VE)
• Average case time complexity: Θ(VE)
• Best case time complexity: Θ(E)
9, WAP to implement DFS and BFS and analyze its time complexity

DFS
Code-
#include <stdio.h>
int a[20][20], reach[20], n;
void dfs(int v)
{
int i;
reach[v] = 1;
for (i = 1; i <= n; i++)
if (a[v][i] && !reach[i])
{
printf("\n %d->%d", v, i);
dfs(i);
}
}
int main()
{
int i, j, count = 0;
printf("\n Enter number of vertices:");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
reach[i] = 0;
for (j = 1; j <= n; j++)
a[i][j] = 0;
}
printf("\n Enter the adjacency matrix:\n");
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
dfs(1);
printf("\n");
for (i = 1; i <= n; i++)
{
if (reach[i])
count++;
}
if (count == n)
printf("\n Graph is connected");
else
printf("\n Graph is not connected");
}
Output-
TIME COMPLEXITY OF DFS IS ALSO O(V+E) WHERE V IS VERTICES AND E IS EDGES.

 BFS
Code-
Output-

TIME COMPLEXITY OF BFS = O(V+E) WHERE V IS VERTICES AND E IS EDGES.


10, WAP to implement 0/1 knapsack using dynamic programming.

Code-

Output-

You might also like