Daa Lab Manual
Daa Lab Manual
No :
Date :
Recursive and Non-Recursive Algorithms - Binary Search
Aim:
To implement recursive and non-recursive algorithm for binary search
Algorithm for Binary Search
Let key be the element we are searching for, and the array be sorted in the ascending order.
1. Compare key with the middle element of the array.
2. If key matches with the middle element, we return the index of the middle element.
3. Else if key is greater than the middle element, it means that key can only lie in
the right half subarray after the middle element. So we repeat steps 1 to 4 for the
right half subarray and leave the left half subarray.
4. Else if key is smaller than the middle element, it means that target can only lie in
the left half subarray before the middle element. So, we repeat steps 1 to 4 for the
left half subarray.
5. We will keep doing that till we find key or there is no element left in the subarray
being considered.
Source code:
#include <stdio.h>
int binarySearch(int arr[], int left, int right, int key) {
if (right >= left) {
int mid = left + (right - left) / 2;
if (arr[mid] == key)
return mid;
if (arr[mid] > key) {
return binarySearch(arr, left, mid - 1, key);
}
return binarySearch(arr, mid + 1, right, key);
}
return -1;
}
int main(void) {
int arr[] = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91};
int size = sizeof(arr) / sizeof(arr[0]);
int key = 23;
int index = binarySearch(arr, 0, size - 1, key);
if (index == -1) {
printf("Element is not present in array");
}
else {
printf("Element is present at index %d", index);
}
return 0;
}
Non-recursive
# include <stdio.h>
int binarysearch(int a[],int low,int high,int key)
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]==key)
{
return mid;
}
else if(key>a[mid])
{
low=mid+1;
}
else if(key<a[mid])
high=mid-1;
}
return -1;
}
int main()
{
int a[20],i,n,key,pos;
printf("enter n value");
scanf("%d",&n);
printf("enter %d elements",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("enter the key element");
scanf("%d",&key);
pos=binarysearch(a,0,n-1,key);
if(pos>=0)
{
printf("element is found at %d",pos+1);
}
else
{
printf("element is not found");
}
getch();
}
Result:
Thus the C program for recursive and non recursive binary search was written and executed
successfully
Exp.No :
Date :
Divide and Conquer-Strassen’s Matrix Multiplication
Aim :
To implement Divide and Conquer-Strassen’s Matrix Multiplication
Algorithm
1.Given two matrices A and B, of size n x n, we divide each matrix into four equal-sized
submatrices, each of size n/2 x n/2.
2.We then define seven intermediate matrices:
P1 = A11 * (B12 - B22)
P2 = (A11 + A12) * B22
P3 = (A21 + A22) * B11
P4 = A22 * (B21 - B11)
P5 = (A11 + A22) * (B11 + B22)
P6 = (A12 - A22) * (B21 + B22)
P7 = (A11 - A21) * (B11 + B12)
3.Next, we recursively compute seven products of these submatrices, i.e., P1, P2, P3, P4, P5,
P6, and P7.
4.Finally, we combine the results to obtain the four submatrices of the resulting matrix C of
size n x n:
C11 = P5 + P4 - P2 + P6
C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1 - P3 - P7
5.Concatenate the four submatrices C11, C12, C21, and C22 to obtain the final result matrix
C.
Source code:
#include<stdio.h>
int main(){
int z[2][2];
int i, j;
int m1, m2, m3, m4 , m5, m6, m7;
int x[2][2] = {
{12, 34},
{22, 10}
};
int y[2][2] = {
{3, 4},
{2, 1}
};
printf("The first matrix is: ");
for(i = 0; i < 2; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", x[i][j]);
}
printf("\nThe second matrix is: ");
for(i = 0; i < 2; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", y[i][j]);
}
m1= (x[0][0] + x[1][1]) * (y[0][0] + y[1][1]);
m2= (x[1][0] + x[1][1]) * y[0][0];
m3= x[0][0] * (y[0][1] - y[1][1]);
m4= x[1][1] * (y[1][0] - y[0][0]);
m5= (x[0][0] + x[0][1]) * y[1][1];
m6= (x[1][0] - x[0][0]) * (y[0][0]+y[0][1]);
m7= (x[0][1] - x[1][1]) * (y[1][0]+y[1][1]);
z[0][0] = m1 + m4- m5 + m7;
z[0][1] = m3 + m5;
z[1][0] = m2 + m4;
z[1][1] = m1 - m2 + m3 + m6;
printf("\nProduct achieved using Strassen's algorithm: ");
for(i = 0; i < 2 ; i++) {
printf("\n");
for(j = 0; j < 2; j++)
printf("%d\t", z[i][j]);
}
return 0;
}
Result:
Thus the Divide and Conquer-Strassen’s Matrix Multiplication can be written and executed
successfully.
Exp.No :
Date :
Decrease and Conquer - Topological sorting
Aim:
To implement Decrease and Conquer - Topological sorting
Algorithm:
Here’s a step-by-step algorithm for topological sorting using Depth First Search (DFS):
Create a graph with n vertices and m-directed edges.
Initialize a stack and a visited array of size n.
For each unvisited vertex in the graph, do the following:
o Call the DFS function with the vertex as the parameter.
o In the DFS function, mark the vertex as visited and recursively call the DFS
function for all unvisited neighbors of the vertex.
o Once all the neighbors have been visited, push the vertex onto the stack.
After all, vertices have been visited, pop elements from the stack and append them to
the output list until the stack is empty.
The resulting list is the topologically sorted order of the graph.
Source code:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
struct Graph {
int V; // No. of vertices
// Pointer to an array containing adjacency lists
struct List* adj;
};
Result:
Thus the C program for Decrease and Conquer - Topological sorting was written and
executed successfully
Exp.No. :
Date :
Transform and Conquer- Heap sort
Aim:
To implement heap sort by using transform and conquer method
Algorithm:
1. Convert to a heap: Use the heapify algorithm to convert the array into a heap.
2. Swap and reduce: Swap the root element with the last element of the heap, then
reduce the heap size by 1.
3. Heapify: Apply heapify to the reduced heap to ensure the largest element is at the root
again.
4. Repeat: Repeat steps 2 and 3 until the heap size is greater than 1.
5. Sort: The array will be sorted in ascending order after the last iteration.
Source code:
#include <stdio.h>
// Heapify function
void heapify(int arr[], int n, int i)
{
int temp, maximum, left_index, right_index;
// HeapSorting function
void heapsort(int arr[], int n)
{
int i, temp;
printf("\n");
heapsort(arr, n);
Result:
Thus, the c program for heap sort by using transform and conquer method was verified and
executed successfully.
Exp.No:
Date:
Dynamic Programming – coin change problem
Aim:
To implement coin change problem by using dynamic programming
Algorithm
Initialize a new array for dynamicprog of length n+1, where n is the number of
different coin changes you want to find.
Because there is only one way to give change for 0 dollars, set dynamicprog[0] to 1.
Iterate through the array for each coin change available and add the value of
dynamicprog[index-coins[i]] to dynamicprog[index] for indexes ranging from '1' to
'n'.
dynamicprog[n] return value
Source code:
#include<stdio.h>
// total count
table[i][j] = x + y;
}
}
return table[n][m-1];
}
Result:
Thus, the c program for coin change problem was verified and executed successfuly
Exp.No:
Date:
Dynamic programming- warshall’s and floyd’s algorithms
Aim:
To implement warshall’s and Floyd’s algorithms by using dynamic programming
Algorithm
Step 1 − Construct an adjacency matrix A with all the costs of edges present in the graph. If
there is no path between two vertices, mark the value as ∞.
Step 2 − Derive another adjacency matrix A1 from A keeping the first row and first column
of the original adjacency matrix intact in A1. And for the remaining values, say A1[i,j],
if A[i,j]>A[i,k]+A[k,j] then replace A1[i,j] with A[i,k]+A[k,j]. Otherwise, do not change the
values. Here, in this step, k = 1 (first vertex acting as pivot).
Step 3 − Repeat Step 2 for all the vertices in the graph by changing the k value for every
pivot vertex until the final matrix is achieved.
Step 4 − The final adjacency matrix obtained is the final solution with all the shortest paths.
Source code:
#include <stdio.h>
void floyds(int b[3][3]) {
int i, j, k;
for (k = 0; k < 3; k++) {
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if ((b[i][k] * b[k][j] != 0) && (i != j)) {
if ((b[i][k] + b[k][j] < b[i][j]) || (b[i][j] == 0)) {
b[i][j] = b[i][k] + b[k][j];
}
}
}
}
}
for (i = 0; i < 3; i++) {
printf("Minimum Cost With Respect to Node: %d\n", i);
for (j = 0; j < 3; j++) {
printf("%d\t", b[i][j]);
}
}
}
int main() {
int b[3][3] = {0};
b[0][1] = 10;
b[1][2] = 15;
b[2][0] = 12;
floyds(b);
return 0;
Result:
Thus, the c program for warshall’s and Floyd’s algorithms by using dynamic programming
was verified and executed successfully.
Exp.No:
Date :
Dynamic programming – Knapsack problem
Aim:
To implement knapsack problem by using dynamic programming
Algorithm:
Create a 2D array dp of size (n+1)x(w+1), where dp[i][j] will store the maximum
result for i items and j capacity of the knapsack.
Initialize the dp[0][j] and dp[i][0] with 0 as the maximum profit will be 0 when either
there are no items or the capacity of the knapsack is zero.
For each item i from 1 to n and for each capacity w from 1 to j.
o If the weight of the current item wt[i-1] is less than or equal to w, then:
o dp[i][w] = max(val[i-1] + dp[i-1][w - wt[i-1]], dp[i-1][j])
o Otherwise, if the weight of the current item is more than w, then:
o dp[i][j] = dp[i-1][j] (same value as without considering the current
item)
Return the value of dp[n][w] that will contain the maximum value that can be
achieved with the full capacity W using all n items.
Source code:
#include<stdio.h>
int max(int a, int b) {
if(a>b){
return a;
} else {
return b;
}
}
int knapsack(int W, int wt[], int val[], int n) {
int i, w;
int knap[n+1][W+1];
for (i = 0; i <= n; i++) {
for (w = 0; w <= W; w++) {
if (i==0 || w==0)
knap[i][w] = 0;
else if (wt[i-1] <= w)
knap[i][w] = max(val[i-1] + knap[i-1][w-wt[i-1]], knap[i-1][w]);
else
knap[i][w] = knap[i-1][w];
}
}
return knap[n][W];
}
int main() {
int val[] = {20, 25, 40};
int wt[] = {25, 20, 30};
int W = 50;
int n = sizeof(val)/sizeof(val[0]);
printf("The solution is : %d", knapsack(W, wt, val, n));
return 0;
}
Result:
Thus, the c program for knapsack problem by using dynamic programming was verified and
executed successfully.
Exp.No:
Date :
Greedy Technique – Dijkstra’s algorithm
Aim:
To implement dijkstra’s algorithm by using greedy technique
Algorithm
Step 1 : Create a set shortPath to store vertices that come in the way of the shortest path tree.
Step 2 : Initialize all distance values as INFINITE and assign distance values as 0 for source
vertex so that it is picked first.
Step 3 : Loop until all vertices of the graph are in the shortPath.
Step 3.1 : Take a new vertex that is not visited and is nearest.
Step 3.2 : Add this vertex to shortPath.
Step 3.3 : For all adjacent vertices of this vertex update distances. Now check every
adjacent vertex of V, if sum of distance of u and weight of edge is elss the update it.
Source code:
#include <limits.h>
#include <stdio.h>
#define V 9
int minDistance(int dist[], bool sptSet[]) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (sptSet[v] == false && dist[v] <= min)
min = dist[v], min_index = v;
return min_index;
}
int printSolution(int dist[], int n) {
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t %d\n", i, dist[i]);
return 0;
}
void dijkstra(int graph[V][V], int src) {
int dist[V];
bool sptSet[V];
for (int i = 0; i < V; i++)
dist[i] = INT_MAX, sptSet[i] = false;
dist[src] = 0;
for (int count = 0; count < V - 1; count++) {
int u = minDistance(dist, sptSet);
sptSet[u] = true;
for (int v = 0; v < V; 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];
}
printSolution(dist, V);
}
int main() {
int graph[V][V] = { { 0, 6, 0, 0, 0, 0, 0, 8, 0 },
{ 6, 0, 8, 0, 0, 0, 0, 13, 0 },
{ 0, 8, 0, 7, 0, 6, 0, 0, 2 },
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
{ 0, 0, 6, 14, 10, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
{ 8, 13, 0, 0, 0, 0, 1, 0, 7 },
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 }
};
dijkstra(graph, 0);
return 0;
}
Result:
Thus, the c program for dijkstra’s algorithm by using greedy technique was verified and
executed successfully.
Exp.No:
Date :
Greedy Technique – Huffman trees and codes
Aim:
To implement Huffman trees and codes by using greedy technique
Algorithm
nput is an array of unique characters along with their frequency of occurrences and output is
Huffman Tree.
1. Create a leaf node for each unique character and build a min heap of all leaf nodes
(Min Heap is used as a priority queue. The value of frequency field is used to compare
two nodes in min heap. Initially, the least frequent character is at root)
2. Extract two nodes with the minimum frequency from the min heap.
3. Create a new internal node with a frequency equal to the sum of the two nodes
frequencies. Make the first extracted node as its left child and the other extracted node
as its right child. Add this node to the min heap.
4. Repeat steps#2 and #3 until the heap contains only one node. The remaining node is
the root node and the tree is complete.
Source code
#include <stdio.h>
#include <stdlib.h>
return temp;
}
// current size is 0
minHeap->size = 0;
minHeap->capacity = capacity;
// A utility function to
// swap two min heap nodes
void swapMinHeapNode(struct MinHeapNode** a,
struct MinHeapNode** b)
if (smallest != idx) {
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
++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;
}
int n = minHeap->size - 1;
int i;
printf("\n");
}
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
{
struct MinHeapNode *left, *right, *top;
// Step 1: Create a min heap of capacity
// equal to size. Initially, there are
// modes equal to size.
struct MinHeap* minHeap
= createAndBuildMinHeap(data, freq, size);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
arr[top] = 0;
printCodes(root->left, arr, top + 1);
}
arr[top] = 1;
printCodes(root->right, arr, top + 1);
}
{
// Construct Huffman Tree
struct MinHeapNode* root
= buildHuffmanTree(data, freq, size);
int arr[MAX_TREE_HT], top = 0;
printCodes(root, arr, top);
}
int main()
{
return 0;
}
Result:
Thus, the c program for Huffman trees and codes by using greedy technique was verified and
executed successfully.
Exp.No:
Date :
Iterative improvement- simplex method
Aim:
To implement iterative improvement by using simplex method
Algorithm
Simplex Algorithm
1. Start with the initial basis associated with identity matrix.
2. Calculate the relative profits.
3. Find the column corresponding to max relative profit. Say column k has the max
Rel. profit. So xk will enter the basis.
4. Perform a min ratio test to determine which variable will leave the basis.
minratiotest:XBr/yrk=min{XBi/yik}minratiotest:XBr/yrk=min{XBi/yik}
Index of the min element i.e 'r' will determine the leaving variable.
The basic variable at index r, will leave the basis.
NOTE: Min ratio test is always performed on positive elements.
5. It's evident that the entered variable will not form an identity matrix, so
we will have to perform row operations to make it identity again.
Find the pivot element. The element at index (r, k) will be the pivot element and
row r will be the pivot row.
6. Divide the rth row by pivot to make it 1. And subtract c*(rth row) from other
rows to make them 0, where c is the coefficient required to make that row 0.
Source code:
#include <stdio.h>
int main() {
int a, b, i, j, k, pc, pr, count;
float pe, min_ratio, ratio, pc_check, store;
printf("Enter number of equations ");
scanf("%d", &a);
printf("Enter number of variables ");
scanf("%d", &b);
float table[a][b];
float rhs[a];
float obj[a];
int row = a + 1;
int col = a + b + 1;
float table2[row][col];
= 0.0;
}
}
while (1) {
for (k = 1; k <= col; k++) {
printf("\n Iteration %d \n ", k - 1);
for (j = 1; j < col; j++) {
printf("\t X%d", j);
}
printf("\t RHS \n");
for (i = 1; i <= row; i++) {
for (j = 1; j <= col; j++) {
printf("\t%0.2f", table2[i][j]);
}
printf("\n");
}
pc = 1, pc_check = 0, count = 0;
for (j = 1; j <= col; j++) {
if (table2[row][j] < 0) {
if (pc_check > table2[row][j]) {
pc_check = table2[row][j];
pc = j;
count = 1;
}
}
if (j == col && count == 0) {
goto okay;
}
}
pr = 0, pe = 1, min_ratio = 1;
for (i = 1; i <= a; i++) {
if (table2[i][pc] > 0) {
ratio = table2[i][col] / table2[i][pc];
if (pr == 0) {
min_ratio = table2[i][col] / table2[i][pc];
count++;
pe = table2[i][pc];
pr = i;
}
if (min_ratio >= ratio && pr != 0) {
if (min_ratio == ratio) {
if (table2[i][pc] < pe) {
pe = table2[i][pc];
pr = i;
}
} else {
min_ratio = ratio;
pr = i;
pe = table2[i][pc];
}
}
}
if (table2[i][pc] < 0 && i == a) {
printf("\n\tUnbounded solution\n");
return 0;
}
}
Result:
Thus, the c program of iterative improvement for simplex method was written and executed
successfully.
Exp.No:
Date :
Backtracking- N-Queen problem
Aim:
To implement N-Queen problem by using backtracking.
Algorithm
Place the first queen in the top-left cell of the chessboard.
After placing a queen in the first cell, mark the position as a part of the solution and
then recursively check if this will lead to a solution.
Now, if placing the queen doesn’t lead to a solution. Then go to the first step and
place queens in other cells. Repeat until all cells are tried.
If placing queen returns a lead to solution return TRUE.
If all queens are placed return TRUE.
If all rows are tried and no solution is found, return FALSE.
Source code:
#include<stdio.h>
#define BOARD_SIZE 5
void displayChess(int chBoard[BOARD_SIZE][BOARD_SIZE]) {
for (int row = 0; row < BOARD_SIZE; row++) {
for (int col = 0; col < BOARD_SIZE; col++)
printf("%d ", chBoard[row][col]);
printf("\n");
}
}
int isQueenPlaceValid(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntRow, int
crntCol) {
// checking if queen is in the left or not
for (int i = 0; i < crntCol; i++)
if (chBoard[crntRow][i])
return 0;
for (int i = crntRow, j = crntCol; i >= 0 && j >= 0; i--, j--)
//checking if queen is in the left upper diagonal or not
if (chBoard[i][j])
return 0;
for (int i = crntRow, j = crntCol; j >= 0 && i < BOARD_SIZE; i++, j--)
//checking if queen is in the left lower diagonal or not
if (chBoard[i][j])
return 0;
return 1;
}
int solveProblem(int chBoard[BOARD_SIZE][BOARD_SIZE], int crntCol) {
//when N queens are placed successfully
if (crntCol >= BOARD_SIZE)
return 1;
// checking placement of queen is possible or not
for (int i = 0; i < BOARD_SIZE; i++) {
if (isQueenPlaceValid(chBoard, i, crntCol)) {
//if validate, place the queen at place (i, col)
chBoard[i][crntCol] = 1;
//Go for the other columns recursively
if (solveProblem(chBoard, crntCol + 1))
return 1;
//When no place is vacant remove that queen
chBoard[i][crntCol] = 0;
}
}
return 0;
}
int displaySolution() {
int chBoard[BOARD_SIZE][BOARD_SIZE];
for(int i = 0; i < BOARD_SIZE; i++)
for(int j = 0; j < BOARD_SIZE; j++)
//set all elements to 0
chBoard[i][j] = 0;
//starting from 0th column
if (solveProblem(chBoard, 0) == 0) {
printf("Solution does not exist");
return 0;
}
displayChess(chBoard);
return 1;
}
int main() {
displaySolution();
return 0;
}
Result:
Thus, the c program N-Queen problem by using backtracking was verified and executed
successfully.
Exp.No:
Date :
Backtracking- subset sum problem
Aim:
To implement subset sum problem by using backtracking
Algorithm
Here's how the backtracking algorithm works for the subset sum problem:
Build a solution: Start with a solution, and then build it piece by piece.
Backtrack: If a piece doesn't fit, backtrack. For example, if the target sum is 5 and
the current subset is {2, 3}, backtrack if the sum is over 5.
Result:
Thus, the c program for subset sum problem by using backtracking.
Exp.No:
Date :
Branch and bound – traveling salesman problem
Aim:
To implement traveling salesman problem by using Branch and bound technique
Algorithm
Here are some steps for the branch and bound algorithm for the TSP:
Create a child node and assign it the next available node number
Label the child node with the two links that correspond to the zeroes in the
opportunity matrix
Compute regrets
Choose the largest regret, and call it Rmax
Source code:
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#define MAX 10
// Function to calculate the second minimum edge cost from a given city
int findSecondMinEdge(int cost[MAX][MAX], int city) {
int first = INT_MAX, second = INT_MAX;
for (int i = 0; i < n; i++) {
if (city == i) continue;
if (cost[city][i] <= first) {
second = first;
first = cost[city][i];
} else if (cost[city][i] < second) {
second = cost[city][i];
}
}
return second;
}
// If the current cost + bound is less than the final cost, explore this path
if (currCost + currBound < finalCost) {
path[level] = i;
visited[i] = true;
tspBranchBound(cost, visited, currBound, currCost, level + 1, path);
}
// Backtrack
currCost -= cost[path[level - 1]][i];
currBound = tempBound;
visited[i] = false;
}
}
}
visited[0] = true;
path[0] = 0;
solveTSP(cost);
return 0;
}
Result:
Thus, the c program traveling salesman problem by using Branch and bound technique was
verified and executed successfully.