ADA LAB Manual CE
ADA LAB Manual CE
LAB Manual
For
Prepared by,
Pradeep B M
Assistant Professor
Dept. of Computer Engineering
MIT Mysore.
CHAPTER 1
INTRODUCTION
The study of algorithms is the concepts of computer science.
It is a standard set of important algorithms, they further our analytical skills& help us
in developing new algorithms for required applications
Algorithm
• String processing
This problem deals with manipulation of characters or strings, string matching, search
and replace, deleting a string in a text etc.
String processing algorithm such as string matching algorithms is used in the design of
assemblers and compliers.
• Graph problems
The graph is a collection of vertices and edges.
Ex: graph traversal problems, topological sorting etc
• Combinatorial problems
These problems are used to find combinatorial object such as permutation and combinations.
Ex: travelling salesman problem, graph coloring problem etc.
• Geometric problems
This problem deal with geometric objects such as points, curves, lines, polygon etc.
Ex: closest-pair problem, convex hull problem
• Numerical problems
These problems involving mathematical manipulations solving equations, computing
differentiations and integrations, evaluating various types of functions etc.
Ex: Gauss elimination method, Newton-Rap son method
2. Graphs
A data structure that consists of a set of nodes and a set of edges that relate the nodes to each
other is called a graph.
Analysis of algorithms
Algorithm efficiency depends on the input size n. And for some algorithms efficiency
depends on type of input.
We have best, worst & average case efficiencies
Worst-case efficiency:
Efficiency (number of times the basic operation will be executed) for the worst case
input of size n. i.e. The algorithm runs the longest among all possible inputs of size n.
Best-case efficiency:
Efficiency (number of times the basic operation will be executed for the best case
input of size n. i.e. The algorithmruns the fastest among all possible inputs of size n.
Average-case efficiency:
Average time taken(number of times the basic operation will be executed) to solve all
the possible instances (random) of the input.
Asymptotic notation is a way of comparing functions that ignores constant factors and
small input sizes.
Three notations used to compare orders of growth of an algorithm’s basic operation
are:
O, Ω, θ notations.
1. Big-oh notation:
2. Big-omega notation:
3. Big-theta notation:
A function t(n) is said to be in θ(g(n)), denoted t(n)€ θ(g(n)),if t(n) is bounded both above
and below by some positive constant multiple of g(n) for all large n i.e., if there exist
some positive constant c
Experiment No: 1
Design and implement C/C++ Program to find Minimum Cost Spanning Tree of a given
connected undirected graph using Kruskal's algorithm.
Kruskal’s algorithm looks at a minimum spanning three for a weighted connected graph
G=(V,E) as an acyclic sub graph with V-1 edges for which the sum of the edge weights is the
smallest.
The algorithm begins by sorting the graph’s edges in increasing order of their weights. Then
starting with the empty sub graph, it scans this sorted list adding the next edge on the list to
the current sub graph if such an inclusion does not create a cycle and simply skipping the
edge otherwise.
When you select a minimum weight path, it will have source and destination vertices. These
two vertices should not have same ancestor or parent. If both the vertices have the same
origin, then it is a cyclic graph.
D C B A
Here CD is the current edge. Vertex C is the parent of D. But C has parent vertex called B.
For B also a parent called A. According to kruskal’s algorithm, we should add all previous
path to the current path. Then here vertex A becomes the parent of vertex D.
Aim : Kruskal's Algorithm for computing the minimum spanning tree is directly based on the
generic MST algorithm. It builds the MST in forest. Prim's algorithm is based ona generic
MST algorithm. It uses greedy approach.
Algorithm:
Kruskal's Algorithm
Start with an empty set A, and select at every stage the shortest edge that has not been chosen
or rejected, regardless of where this edge is situated in graph.
• Initially, each vertex is in its own tree in forest.
• Then, algorithm considers each edge in turn, order by increasing weight.
• If an edge(u,v) connects two different trees, then(u,v) is added to the set of edges of the
MST,and two trees connected by an edge(u,v)aremergedintoasingletree.
• On the other hand, if an edge(u,v )connects two vertices in the same tree, then
• edge(u,v) is discarded.
Program:
#include<stdio.h>
int ne=1,
min_cost=0;
void main ( )
{
int n,i,j, min,a,u,b,v,cost[20][20],parent[20];
printf("Enter the no. of vertices:");
scanf("%d",&n);
printf("\nEnter the cost matrix:\n");
Viva questions
1 Which are the data structures is used to represent the graph.
2 What is tree?
3 What is spanning tree?
4 What is MST (Minimum-cost Spanning Tree)?
5 Difference between Greedyalgorithm and Dynamic algorithm method.
Experiment No: 2
Design and implement C/C++ Program to find Minimum Cost Spanning Tree of a given
connected undirected graph using Prim's algorithm.
Objectives:
This Program enable students to :
Learn Prim's algorithm to find shortest paths.
Find Minimum Cost Spanning Tree ofa given undirected graph using Prim's
algorithm
Choose a node and build a tree from there selecting at every stage the shortest available edge
that can extend the tree to an additional node.
• Prim'salgorithmhasthepropertythattheedgesinthesetAalwaysformasingletree.
• We begin with some vertex in a given graph G= (V, E), defining the initial set of vertices A.
• In each iteration, we choose a minimum-weight edge(u,v),connecting a vertex v in the set A
to the vertex u outside of set A.
• ThevertexuisbroughtintoA.Thisprocessisrepeateduntilaspanningtreeisformed.
• Like Kruskal's algorithm, here too,the import ant fact about MST sis weal ways choose the
smallest-weight edge joining a vertex inside set A to the one outside the set A.
• The implication of this fact is that It adds on ly edges that are safe for A;
• Therefore, when the algorithm terminates, the edges in set A form a MST
Program:
#include<stdio.h>
int a,b,u,v,n,i,j,ne=1;
int visited [10]={0}, min,mincost=0,cost[10][10];
void main ( )
{
printf("\n Enter the number of nodes:");
scanf("%d",&n);
printf("\n Enter the adjacency matrix:\n");
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&cost[i][j]); if(cost[i][j]==0)
cost[i][j]=999;
}
visited[1]=1; printf("\n");
while(ne<n)
{
for(i=1,min=999;i<=n;i++)
for(j=1;j<=n;j++)
if(cost[i][j]<min)
Experiment No 3
a) Design and implement C/C++ Program to solve All-Pairs Shortest Paths problem using
Floyd's algorithm.
Floyds algorithm is a classic example for the application of dynamic programming. It is used
to compute the shortest distance between every two pair of nodes ina given graph and hence it
is also called “all-pair shortest path”algorithm
Program:
#include <stdio.h>
#include <limits.h>
#define V 4
void floydWarshall(int graph[V][V])
{
int dist[V][V],i,j,k;
for (i = 0; i < V; i++)
for ( j = 0; j < V; j++)
dist[i][j] = graph[i][j];
for ( k = 0; k < V; k++)
for ( i = 0; i < V; i++)
for ( j = 0; j < V; j++)
# include <stdio.h>
int n,a[10][10],p[10][10];
void path()
{
int i,j,k; for(i=0;i<n;i++)
for(j=0;j<n;j++) p[i][j]=a[i][j];
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(p[i][k]==1&&p[k][j]==1)
p[i][j]=1;
}
void main ()
{
int i,j;
printf("Enter the number of nodes:");
scanf("%d",&n);
printf("\nEnter the adjacency matrix:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
path();
printf("\nThe path matrix is shown below\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++) printf("%d ",p[i][j]);
printf("\n");
}
}
Experiment No. 4
Design and implement C/C++ Program to find shortest paths from a given vertex in a
weighted connected graph to other vertices using Dijkstra's algorithm.
Dijkstra’s algorithm finds shortest paths to a graph’s vertices in order of their distance from a
given source. First, it finds the shortest path from the source to a vertex nearest to it, then to a
second nearest and so on.
Experiment No. 5
Design and implement C/C++ Program to obtain the Topological ordering of vertices in a
given digraph.
Method: Source removal method. Each vertex may have an encoming endge or may not have
incoming edge. Vertex with no incoming edges deleted along with all the edges outgoing
from it. (If there are several sources, break tie arbitrarily. If there none, stop because the
problem cannot be solved). The order in which the vertices are deleted is to be displayed.
Here While numbering the vertices of the graph, remember to assign 1 to vertex with no
incoming edge.
A situation can be modeled by a graph in which vertices represent courses and directed edges
indicate prerequisite requirements. In terms of this digraph, the question is whether we can
list its vertices in such an order that for every edge in graph, the vertex where the edge starts
is listed before the vertex where the edge ends. This problem is called topological sorting. If a
directed graph has a directed cycle, then sorting is not possible. For topological sorting to be
possible, a digraph must be a dag (Directed Acyclic graph). It turns out that being a dag is not
only necessary but also sufficient for topological sorting to be possible. i.e if a diagraph has
no cycles, the topological sorting problem for it has a solution. There are two efficient
algorithms that both verify whether a digraph is a dag and if it is, produce an ordering vertices
that solves the topological sorting problem.
First algorithm is DFS. 2nd algorithm is Source removal method. Second method is based on
decrease and conquer technique: Repeatedly identifying in a remaining digraph. A
source,which is a vertex with no incoming edges and delete it along with all the edges
outgoing from it. (If there are several sources, break tie arbitrarily. If there none, stop
because the problem cannot be solved). The order in which the vertices are deleted yields a
solution to the topological sorting problem.The solution obtained by the source removal
algorithm is different from the one obtained by the DFS based algorithm. Both of them are
correct, of course. The topological sorting problem may have several alternative solutions.
Program:
#include<stdio.h>
void findindegree(int [10][10],int[10],int);
void topological(int,int [10][10]);
void main ()
{
int a[10][10],i,j,n;
printf("Enter the number of nodes:");
scanf("%d",&n);
printf("\nEnter the adjacency matrix\n");
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
Experiment No. 6
Design and implement C/C++ Program to solve 0/1 Knapsack problem using Dynamic
Programming method.
Program:
#include<stdio.h>
#define MAX 50
int p[MAX],w[MAX],n;
int knapsack(int,int);
int max(int,int);
void main()
{
int m,i,optsoln;
printf("Enter no. of objects: ");
scanf("%d",&n);
printf("\nEnter the weights:\n");
for(i=1;i<=n;i++)
scanf("%d",&w[i]);
printf("\nEnter the profits:\n");
for(i=1;i<=n;i++)
scanf("%d",&p[i]);
printf("\nEnter the knapsack capacity:");
Output:
Enter no. of objects: 3 Enter the weights:
100 10 14
Enter the profits:
20 18 15
Enter the knapsack capacity:116 The optimal solution is:38
Experiment No. 7
Design and implement C/C++ Program to solve discrete Knapsack and continuous Knapsack
problems using greedy approximation method.
Program:
#include <stdio.h>
#include <stdlib.h>
// Structure to represent an item
struct Item
{
int value;
int weight;
};
// Function to compare two items based on their value-to-weight ratio
int compare(const void *a, const void *b)
{
double ratio1 = (double)((struct Item *)a)->value / ((struct Item *)a)->weight;
double ratio2 = (double)((struct Item *)b)->value / ((struct Item *)b)->weight;
Experiment No.8
Design and implement C/C++ Program to find a subset of a given set S = {sl , s2,.....,sn} of n
positive integers whose sum is equal to a given positive integer d.
Aim:
An instance of the Subset Sum problem Is a pair(S,t),where S={x1,x2, ............. ,xn} is a set of
Positive integers and t (the target) is a positive integer. The decision problem asks for a subset
of S whose sum is as large as possible, but not larger than t.
This problem is NP-complete.
This problem arises in practical applications. Similar to the knapsack problem we may have a
truck that can carry at most t pounds and we have n different boxes to ship and the ith box
weighs xi pounds. The naive approach of computing the sum of the elements of every subset
of S and then selecting the best requires exponential time. Below we present an exponential
time exact algorithm.
#include<stdio.h>
void subset(int,int,int);
int x[10],w[10],d,count=0;
void main()
{
int i,n,sum=0;
printf("Enter the no. of elements: ");
scanf("%d",&n);
printf("\nEnter the elements in ascending order:\n");
for(i=0;i<n;i++)
scanf("%d",&w[i]); printf("\nEnter the sum: ");
scanf("%d",&d);
for(i=0;i<n;i++)
sum=sum+w[i];
if(sum<d)
{
printf("No solution\n");
return;
}
subset(0,0,sum);
if(count==0)
{
printf("No solution\n");
return;
}
}
void subset(int cs,int k,int r)
{
int i; x[k]=1; if(cs+w[k]==d)
{
Experiment No. 9
Design and implement C/C++ Program to sort a given set of n integer elements using
Selection Sort method and compute its time complexity. Run the program for varied values of
n> 5000 and record the time taken to sort. Plot a graph of the time taken versus n. The
elements can be read from a file or can be generated using the random number generator.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Function to perform selection sort
void selectionSort(int arr[], int n)
{
int i, j, minIndex, temp;
for (i = 0; i < n - 1; i++)
{
minIndex = i;
for (j = i + 1; j < n; j++)
{
Experiment No. 10
Design and implement C/C++ Program to sort a given set of n integer elements using Quick
Sort method and compute its time complexity. Run the program for varied values of n> 5000
and record the time taken to sort. Plot a graph of the time taken versus n. The elements can be
read from a file or can be generated using the random number generator.
Quick sort is one of the sorting algorithms working on the Divide and Conquer principle.
Quick sort works by finding an element, called pivot, in the given array and partitions the
array into three sub arrays such that The left sub array contains all elements which are less
than or equal to the pivot The middle sub arrays contains pivot The right sub array contains
all elements which are greater than or equal to the pivot.
Quick sort is well-known sorting algorithms based on the divide and conquer technique.
Quicksort divide s its input elements according to the i value. Specifically, it rearrange s
elements of a given array A[n-1]to achieve its partition, as it uation where all the elements
before some position s are smaller than or equal to A[s] and all the elements after some
position s are greater than or equal to A[s].We call this element the pivot.
After a partition has been achieved, A[s] will be in its final position in the sorted array, and
we can continue sorting the two sub arrays of the elements preceding and following A[s]
independently.
Program:
#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;
*b = temp;
}
// Function to partition the array and return the pivot index
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low - 1),j;
for (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);
}
Pradeep B M, Dept. of CE, MITMysore. Page 33
Analysis and Design of Algorithms Lab
// Function to perform Quick Sort
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// Function to generate random numbers between 0 and 999
int generateRandomNumber()
{
return rand() % 1000;
}
int main()
{
// Set n value
int n= 6000;
// Allocate memory for the array
int* arr = (int*)malloc(n * sizeof(int));
// Generate random elements for the array srand(time(NULL));
printf("Random numbers for n = %d:\n", n);
for ( i = 0; i < n; i++)
{
arr[i] = generateRandomNumber();
printf("%d ", arr[i]);
}
printf("\n");
// Record the start time
clock_t start = clock();
// Perform quick sort
quickSort(arr, 0, n - 1);
// Record the end time
clock_t end = clock();
// Calculate the time taken for sorting
double time_taken = ((double)(end - start)) / CLOCKS_PER_SEC;
// Output the time taken to sort for the current value of n
printf("\nTime taken to sort for n = %d: %lf seconds\n\n", n, time_taken);
// Display sorted numbers
printf("Sorted numbers for n = %d:\n", n);
for( i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n\n");
// Free the dynamically allocated memory free(arr);
return 0;
}
Experiment No. 11
Design and implement C/C++ Program to sort a given set of n integer elements using Merge
Sort method and compute its time complexity. Run the program for varied values of n> 5000,
and record the time taken to sort. Plot a graph of the time taken versus n. The elements can be
read from a file or can be generated using the random number generator.
The basic operation in merge sort is comparison and swapping. Merge sort algorithm calls it
self recursively. Merge sort divides the array into sub arrays based on the position of the
elements whereas quick sort divides the array into sub arrays based on the value of the
elements.
Merge sort requires an auxiliary array to do the merging.The merging of two subarrays,which
are already sorted, into an auxiliary array can be done in O(n) where n is the total number of
elementsinboththesubarrays.Thisispossiblebecauseboththesubarraysaresorted.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Merge two subarrays of arr[]
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
// Create temporary arrays
int L[n1], R[n2];
// Copy data to temporary arrays L[] and R[]
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
Pradeep B M, Dept. of CE, MITMysore. Page 36
Analysis and Design of Algorithms Lab
// Merge the temporary arrays back into arr[l..r]
i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray k = l; // Initial index of merged subarray
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
// Copy the remaining elements of L[], if there are any
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
// Copy the remaining elements of R[], if there are any
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
// Merge sort function
void mergeSort(int arr[], int l, int r)
{
if (l < r)
{
// Same as (l+r)/2, but avoids overflow for large l and r
int m = l + (r - l) / 2;
// Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
// Merge the sorted halves
merge(arr, l, m, r);
}
}
// Function to generate random numbers between 0 and 999
int generateRandomNumber()
{
return rand() % 1000;
}
Experiment No. 12
Design and implement C/C++ Program for N Queen's problem using Backtracking.
Algorithm:
Input:
A 2D array graph[V][V] where V is the number of vertices in graph and graph[V][V] is
adjacency matrix representation of the graph.
A value graph[i][j] is 1 if there is a direct edge from i to j,
otherwise graph[i][j] is 0.
Output:
An array path[V] that should contain the Hamiltonian Path. path[i] should represent the ith
vertexintheHamiltonianPath.Thecodeshouldalsoreturnfalseifthereis no Hamiltonian Cycle in the
graph.
Backtracking Algorithm
Program:
#include <stdio.h>
#include <stdbool.h>
#define MAX 100
int board[MAX][MAX];
// Function to print the board
void printBoard(int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
}
// Function to check if it's safe to place a queen at board[row][col]
bool isSafe(int n, int row, int col)
{
// Check the column
for (int i = 0; i < row; i++)
{
if (board[i][col] == 1)
{
return false;
}
}