Daa Lab Manual Kcs553 2022-23
Daa Lab Manual Kcs553 2022-23
FACULTY NAME:
S.NO PRACTICAL
11 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 non graph sheet. The elements can be
read from a file or can be generated using the random number generator.
Demonstrate using Java how the divide and- conquer method works along with its
time complexity analysis: worst case, average case and best case.
12 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 non graph sheet. The elements can be
read from a file or can be generated using the random number generator.
Demonstrate how the divide and- conquer method works along with its time
complexity analysis: worst case, average case and best case.
13 Implement the 0/1 Knapsack problem using
(a) Dynamic Programming method (b) Greedy method
2
14 From a given vertex in a weighted connected graph, find shortest paths to other
vertices using Dijkstra's algorithm.
15 Find Minimum Cost Spanning Tree of a given connected undirected graph using
Kruskal's algorithm. Use Union-Find algorithms in your program.
16 Find Minimum Cost Spanning Tree of a given undirected graph using Prim’s
Algorithm
17 Write programs to (a) Implement All-Pairs Shortest Paths problem using Floyd's
algorithm. (b) Implement Travelling Salesperson problem using Dynamic
programming.
18 Design and implement 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. For example, if S = {1, 2,
5, 6, 8} and d= 9, there are two solutions {1,2,6}and {1,8}. Display a suitable
message if the given problem instance doesn't have a solution.
19 Design and implement to find all Hamiltonian Cycles in a connected undirected
Graph G of n vertices using backtracking principle.
3
1. RECURSIVE BINARY & LINEAR SEARCH
A linear search scans one item at a time, without jumping to any item.
The worst-case complexity is O(n), sometimes known an O(n) search
Time taken to search elements keep increasing as the number of elements are increased.
A binary search however, cut down your search to half as soon as you find middle of a sorted
list.
The middle element is looked to check if it is greater than or less than the value to be
searched.
Accordingly, search is done to either half of the given list
Important Differences
Input data needs to be sorted in Binary Search and not in Linear Search
Linear search does the sequential access whereas Binary search access data randomly.
Time complexity of linear search is O(n) & Binary search has time complexity O(log n).
Linear search performs equality comparisons and Binary search performs ordering
comparisons
ALGORITHM
4
PSEUDO-CODE
end procedure
Procedure binary_search
A ← sorted array
n ← size of array
x ← value to be searched
Set lowerBound =
1 Set upperBound
=n
if A[midPoint] < x
set lowerBound = midPoint + 1
if A[midPoint] > x
set upperBound = midPoint - 1
if A[midPoint] = x
EXIT: x found at location midPoint
end while
end procedure
PROGRAM
#include <stdio.h>
#define MAX_LEN
5
10
6
void b_search_recursive(int l[],int num,int ele);
void read_list(int l[],int num);
void print_list(int l[],int num);
void main ( )
{
int l[MAX_LEN], num, ele;
int ch;
clrscr();
printf("======================================================");
printf("\n\t\t\tMENU");
printf("\n=====================================================");
printf("\n[1] Linary Search");
printf("\n[2] Binary Search");
printf("\n\nEnter your
Choice:"); scanf("%d",&ch);
switch(ch)
{
case 1:printf("\n**Linear Search**\n");
l_search_recursive(l,num,ele);
getch();
break;
7
break;
}
}
getch();
}
/*end main*/
9
2. HEAPSORT
Combines the better attributes of merge sort and insertion sort.
Like merge sort, but unlike insertion sort, running time is O(n lg
n). Like insertion sort, but unlike merge sort, sorts in place.
Introduces an algorithm design technique
Create data structure (heap) to manage information during the execution of an
algorithm. The heap has other applications beside sorting- Priority Queues.
Example
ALGORITHM
10
3. Repeat above steps while size of heap is greater than 1.
PSEUDO-CODE
MaxHeapify(A, i)
1. l left(i)
2. r right(i)
3. if l heap-size[A] and A[l] > A[i]
4. then largest l
5. else largest i
6. if r heap-size[A] and A[r] > A[largest]
7. then largest r
8. if largest i
9. then exchange A[i] A[largest]
10. MaxHeapify(A, largest)
BuildMaxHeap(A)
1. heap-size[A] length[A]
2. for i length[A]/2 downto 1
3. do MaxHeapify(A, i)
HeapSort(A)
1. Build-Max-Heap(A)
2. for i length[A] downto 2
3. do exchange A[1] A[i]
4. heap-size[A] heap-size[A] – 1
5. MaxHeapify(A, 1)
PROGRAM
#include<stdio.h>
#include<conio.h>
void max_heapify(int *,int);
void build_max_heap(int
11
*,int);
12
void heapsort(int *,int);
void swap(int,int);
int heapsize;
int main()
{
int *arr,n,i;
printf("Enter no. of elements = ");
scanf("%d",&n);
arr=(int *)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
{
printf("Enter array elements =
"); scanf("%d",&arr[i]);
}
//heapsize = n;
heapsort(arr,n); printf("\
nAfter heapsort \n");
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
void heapsort(int *arr,int len)
{
int i;
build_max_heap(arr,len);
for(i= len-1;i>=1;i--)
{
swap(&arr[0],&arr[i]);
heapsize = heapsize -1;
max_heapify(arr,0);
}
}
void max_heapify(int *arr,int i)
{
int l=2*i,r=2*i+1,largest;
if(l<heapsize &&
arr[l]>arr[i])
13
largest = l;
14
else
largest = i;
if(r<heapsize &&
arr[r]>arr[largest]) largest = r;
if(largest != i)
{
swap(&arr[i],&arr[largest]);
max_heapify(arr,largest);
}
}
void build_max_heap(int *arr,int len)
{
heapsize =
len; int i;
for(i =len/2;i>=0;i--)
{
max_heapify(arr,i);
}
}
void swap(int *a ,int *b)
{
int temp = *a;
*a= *b;
*b= temp;
}
15
3. MERGE SORT
1. Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element
is considered sorted).
2. Repeatedly merge sublists to produce new sorted sublists until there is only 1
sublist remaining. This will be the sorted list.
Example:
ALGORITHM:
PSEUDO-CODE
16
var l1 as array = a[0] ... a[n/2]
var l2 as array = a[n/2+1] ...
a[n]
l1 = mergesort( l1
) l2 = mergesort(
l2 )
) var c as array
while ( a and b have elements )
if ( a[0] > b[0] )
add b[0] to the end of c
remove b[0] from b
else
add a[0] to the end of
c remove a[0] from a
end if
end while
return c
end procedure
PROGRAM
17
#include <iostream>
18
using namespace
std; #include
<conio.h>
void merge(int *,int, int , int );
void mergesort(int *a, int low, int high)
{
int mid;
if (low < high)
{
mid=(low+high)/2;
mergesort(a,low,mid);
mergesort(a,mid+1,high);
merge(a,low,high,mid);
}
return;
}
void merge(int *a, int low, int high, int mid)
{
int i, j, k,
c[50]; i = low;
k = low;
j = mid + 1;
while (i <= mid && j <= high)
{
if (a[i] < a[j])
{
c[k] = a[i];
k++;
i++;
}
else
{
c[k] = a[j];
k++;
j++;
}
}
while (i <= mid)
{
c[k] = a[i];
k++;
i++;
}
while (j <= high)
{
19
c[k] = a[j];
20
k++;
j++;
}
for (i = low; i < k; i++)
{
a[i] = c[i];
}
}
int main()
{
int a[20], i, b[20];
cout<<"enter the elements\
n"; for (i = 0; i < 5; i++)
{
cin>>a[i];
}
mergesort(a, 0, 4);
cout<<"sorted array\n";
for (i = 0; i < 5; i++)
{
cout<<a[i];
}
cout<<"enter the elements\
n"; for (i = 0; i < 5; i++)
{
cin>>b[i];
}
mergesort(b, 0, 4);
cout<<"sorted array\n";
for (i = 0; i < 5; i++)
{
cout<<b[i];
}
getch();
}
21
4. SELECTION SORT
The selection sort algorithm sorts an array by repeatedly finding the minimum element
considering ascending order) from unsorted part and putting it at the beginning. The algorithm
maintains two subarrays in a given array.
1. The subarray which is already sorted.
2. Remaining subarray which is unsorted.
In every iteration of selection sort, the minimum element (considering ascending order) from
the unsorted subarray is picked and moved to the sorted subarray.
Time Complexity: O(n2) as there are two nested loops.
Example:
ALGORITHM
PSEUDO-CODE
procedure selection
sort list : array of
items
22
n : size of list
23
for i = 1 to n - 1
/* set current element as minimum*/
min = i
*/ for j = i+1 to n
if list[j] < list[min] then
min = j;
end if
end for
end procedure
PROGRAM
#include <stdio.h>
25
5. INSERTION SORT
Insertion sort algorithm removes an element from the sorting list, and placing it into the
correct position in the already sorted part of the list, until no input elements left. The insertion
sort algorithm complexity depends on the input list. If the list is already sorted we have best
case,which has linear complexity O(n). If the list is reversed then we have worst case, quadratic
running time O(n^2). And the average case is also quadratic running time O(n^2), which make
the insertion sort not practical algorithm of choice for large n( where n is number of element in
the data structure), however insertion sort is one of the fastest algorithms for sorting very small
arrays.
A[]=[7,4,5,2].
ALGORITHM
27
4. Shift all the elements in the sorted sub-list that is greater than the value to be sorted
5. Insert the value
6. Repeat until list is sorted
PSEUDO-CODE
for i ← 1 to length(A) -
1j←i
while j > 0 and A[j-1] > A[j]
swap A[j] and A[j-1]
j←j-
1 end
while
end for
PROGRAM:
#include <cstdlib>
#include <iostream>
//member function
void insertion_sort(int arr[], int
length); void print_array(int array[],int
size);
int main()
{
int array[5]=
{5,4,3,2,1};
insertion_sort(array,5);
return 0;
}//end of main
28
{
j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
29
tmp = arr[j];
arr[j] = arr[j -
1]; arr[j - 1] =
tmp;
j--;
}//end of while loop
print_array(arr,5);
}//end of for loop
}//end of insertion_sort.
30
6. QUICK SORT
Quicksort is a divide and conquer algorithm. Quicksort first divides a large array into two
smaller sub-arrays: the low elements and the high elements. Quicksort can then recursively
sort the sub-arrays.
The steps are:
Example:
31
The shaded element is the pivot. It is always chosen as the last element of the partition. However,
always choosing the last element in the partition as the pivot in this way results in
poorperformance (O(n²)) on already sorted arrays, or arrays of identical elements. Since sub-
arrays ofsorted / identical elements crop up a lot towards the end of a sorting procedure on a
large set, versions of the quicksort algorithm which choose the pivot as the middle element run
much morequickly than the algorithm described in this diagram on large sets of numbers.
ALGORITHM
PSEUDO-CODE
while True do
while A[++leftPointer] < pivot do
//do-nothing
end while
32
if leftPointer >=
rightPointer break
else
swap leftPointer,rightPointer
end if
end while
swap leftPointer,right
return leftPointer
end function
if right-left <= 0
return
else
pivot = A[right]
partition = partitionFunc(left, right,
pivot) quickSort(left,partition-1)
quickSort(partition+1,right)
end if
end procedure
PROGRAM
#include <iostream>
#include <vector>
using namespace
std;
/**
* Partition the elements of A, such that you first have elements smaller than
* "who", followed by eleemnts larger than "who". Return the last poistion of an
* element smaller or equal to "who".
*/
int partition(vector<int>& A, int left, int right, int who) {
33
for (int i=left; i<right; ++i) {
34
if (A[i] <= who) {
swap(A[i], A[left]);
left ++;
}
}
return left - 1;
}
/**
* Quick sort vector A, between index "left" and index "right".
*/
void qsort(vector<int>& A, int left, int right)
{ if (left >= right) return;
void printVector(vector<int>& A)
{ for (int i=0; i<A.size(); ++i) {
cout << A[i] << " ";
}
cout << endl;
}
void testPartition() {
int elements[] = {1, 3, 1, 1, 3};
vector<int> A(elements, elements +
5); int n = partition(A, 0, 5, 1);
cout << n <<
endl;
printVector(A);
}
35
void testSort() {
int elements[] = {1, 12, 2, 2, 2, 6, 20, 22};
36
vector<int> A(elements, elements +
8); qsort(A, 0, A.size());
printVector(A);
}
int main ()
{
testPartition();
cout << "--------------" << endl;
testSort();
return 0;
}
37
7. KNAPSACK PROBLEM USING GREEDY SOLUTION
Given a set of items, each with a weight and a value, determine a subset of items to include in a
collection so that the total weight is less than or equal to a given limit and the total value is as
large as possible.
Applications: In many cases of resource allocation along with some constraint, the problem can
be derived in a similar way of Knapsack problem. Following is a set of example.
Problem Scenario
A thief is robbing a store and can carry a maximal weight of W into his knapsack. There are n
items available in the store and weight of ith item is w i and its profit is pi. What items should the
thief take?
In this context, the items should be selected in such a way that the thief will carry those items for
which he will gain maximum profit. Hence, the objective of the thief is to maximize the profit.
In the case of fractional knapsack, items can be broken into smaller pieces, hence the thief can
select fractions of items. According to the problem statement,
In this fractional Knapsack problem, items can be broken into smaller pieces. So, the thief may
take only a fraction xi of ith item.
0⩽xi⩽1
38
The ith item contributes the weight xi.wi to the total weight in the knapsack and profit xi.pi to
the total profit.
subject to constraint,
It is clear that an optimal solution must fill the knapsack exactly, otherwise we could add a
fraction of one of the remaining items and increase the overall profit. Thus, an optimal solution
can be obtained by
In this context, first we need to sort those items according to the value of pi/wi, so that
(pi+1)/(wi+1)
≤ pi/wi . Here, x is an array to store the fraction of items.
ALGORITHM
Assume knapsack holds weight W and items have value pi and weight wi
Rank items by value/weight ratio: pi / wi
Thus: pi / wi ≥ pj / wj, for all i ≤ j
Consider items in order of decreasing ratio
Take as much of each item as possible
PSEUDO-CODE
PROGRAM
# include<stdio.h>
for (i = 0; i < n; i+
+) x[i] = 0.0;
if (i < n)
x[i] = u / weight[i];
tp = tp + (x[i] * profit[i]);
int main() {
float weight[20], profit[20], capacity;
int num, i, j;
float ratio[20], temp;
temp = weight[j];
weight[j] = weight[i];
weight[i] = temp;
temp = profit[j];
profit[j] = profit[i];
profit[i] = temp;
}
}
}
Travelling salesman problem is the most notorious computational problem. We can use brute-
force approach to evaluate every possible tour and select the best one. For n number of vertices
in a graph, there are (n - 1)! number of possibilities. Instead of brute-force using dynamic
programming approach, the solution can be obtained in lesser time, though there is no
polynomial time algorithm.
Let us consider a graph G = (V, E), where V is a set of cities and E is a set of weighted edges. An
edge e(u, v) represents that vertices u and v are connected. Distance between vertex u and v is
d(u, v), which should be non-negative.
Suppose we have started at city 1 and after visiting some cities now we are in city j. Hence, this
is a partial tour. We certainly need to know j, since this will determine which cities are most
convenient to visit next. We also need to know all the cities visited so far, so that we don't repeat
any of them. Hence, this is an appropriate sub-problem.
For a subset of cities S Є {1, 2, 3, ... , n} that includes 1, and j Є S, let C(S, j) be the length of the
shortest path visiting each node in S exactly once, starting at 1 and ending at j.
When |S| > 1, we define C(S, 1) = 𝖺 since the path cannot start and end at 1.
Now, let express C(S, j) in terms of smaller sub-problems. We need to start at 1 and end at j. We
should select the next city in such a way that
There are at the most 2n.n sub-problems and each one takes linear time to solve. Therefore, the
total running time is O(2 n.n2).
ALGORITHM
1. Consider city 1 as the starting and ending point. Since route is cyclic, we can
consider any point as starting point.
2. Generate all (n-1)! permutations of cities.
3. Calculate cost of every permutation and keep track of minimum cost permutation.
4. Return the permutation with minimum cost.
42
PSEUDO-CODE
C ({1}, 1) = 0
for s = 2 to n do
for all subsets S Є {1, 2, 3, … , n} of size s and containing 1
C (S, 1) = ∞
for all j Є S and j ≠ 1
C (S, j) = min {C (S – {j}, i) + d(i, j) for i Є S and i ≠ j}
Return minj C ({1, 2, 3, …, n}, j) + d(j, i)
PROGRAM
#include<stdio.h>
int ary[10][10],completed[10],n,cost=0;
void takeInput()
{
int i,j;
completed[i]=0;
}
completed[city]=1;
printf("%d--->",city+1);
ncity=least(city);
if(ncity==999)
{
ncity=0;
printf("%d",ncity+1);
cost+=ary[city][ncity];
return;
}
mincost(ncity);
}
int least(int c)
{
int i,nc=999;
int min=999,kmin;
if(min!=999)
cost+=kmin;
return nc;
}
44
int main()
{
takeInput();
",cost);
return 0;
}
45
9. MINIMUM SPANNING TREE (KRUSKAL’S ALGORITHM)
Prim's algorithm is a greedy algorithm that finds a minimum spanning tree for a weighted
undirected graph. This means it finds a subset of the edges that forms a tree that includes every
vertex, where the total weight of all the edges in the tree is minimized. The algorithm operates by
building this tree one vertex at a time, from an arbitrary starting vertex, at each step adding the
cheapest possible connection from the tree to another vertex.
1. Initialize a tree with a single vertex, chosen arbitrarily from the graph.
2. Grow the tree by one edge: of the edges that connect the tree to vertices not yet in
the tree, find the minimum-weight edge, and transfer it to the tree.
3. Repeat step 2 (until all vertices are in the tree).
ALGORITHM
PSEUDO-CODE
A=∅
foreach v ∈ G.V
MAKE-SET(v)
foreach (u, v) in G.E ordered by weight(u, v),
increasing if FIND-SET(u) ≠ FIND-SET(v)
A = A 𝖴 {(u, v)}
UNION(FIND-SET(u), FIND-SET(v))
return A
PROGRAM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
46
struct Edge
{
int src, dest, weight;
};
return graph;
}
48
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}
50
// Step 1: Sort all the edges in non-decreasing
// order of their weight. If we are not allowed to
// change the given graph, we can create a copy of
// array of edges
qsort(graph->edge, graph->E, sizeof(graph->edge[0]), myComp);
52
10. N QUEEN PROBLEM USING BACK TRACKING
If we imagine the squares of the chessboard being numbered as the indices of the two
dimensional array A(l:n, l:n) then we observe that for every element on the same diagonal which
runs from the upper left to the lower right, each element has the same "row - column" value.
Also, every element on the same diagonal which goes from the upper right to the lower left has
the same "row + column" value. Suppose two queens are placed at positions (i,j) and (k, /).Then
by the above they are on the same diagonal only if
i - j = k - I or i + j = k + I.
The first equation implies
j-l=i-k
while the second implies
j-l=k-i
Therefore two queens lie on the same diagonal if and only if lj - /I = Ii - kl.
ALGORITHM
Procedure PLACE(k) returns a boolean value which is true if the kth queen can be placed at
the current value of x(k). It tests both if X(k) is distinct from all previous values X(l), ... , X(k -
1) and also if there is no other queen on the same diagonal. Its computing time is O(k - 1).
PLACE(k)
I /returns true if a queen can be placed in kth row and/ I I IX(k)th column. Otherwise it returns
false.I I /IX is a global array whose first k values have been set.I I I I ABS(r) returns the
absolute value of rl I global X(l: k ); integer i, k
for i - 1 to k do
if X(i) = X(k) I !two in the same column//
or ABS(X(i) - X(k)) = ABS(i - k) //in the same diagonal//
then retum(false)
endif
repeat
return( true)
end PLACE
NQUEENS(n)
I /using backtracking this procedure prints all possible placements of / I I In queens on an n x n
chessboard so that they are nonattacking/ I
integer k, n, X(l:n)
X(l) - 0; k - 1 Ilk is the current row; X(k) the current column/ I
53
while k > 0 do //for aU rows do//
X(k) - X(k) + 1 I /move to the next column/ I
While X(k)<=n and not PLACE(k) do //can this queen be placed?//
X(k) - X(k) + 1
repeat
if X(k) ~ n ! la position is found//
then if k = n I !is a solution complete? I I
then print(X) //yes, print the array/ I
else k - k + 1; X(k) - 0 I Igo to the next row//
endif
else k - k - 1 I /backtrack/ I
endif
repeat
endNQUEENS
PROGRAM
int board[20];
int count;
void main()
{
int n,i,j;
void queen(int row, int
n); clrscr();
printf("\n\t Program for queen's using
backtracking"); printf("Enter number of queen's ");
scanf("%d",&n);
queen(1,n); //trace using
backtrack getch();
}
54
/*This function is for printing the solution to n-queen's
problem*/ void print_board(int n)
{
int i,j;
printf("\n\n solution %d:\n\n",++count);
//number of solution
for(i=1;i<=n;i++)
{
printf("\t%d",i);
}
for(i=1;i<=n;i++)
{
printf("\n\n%d",i);
for(j=1;j<=n;j++) //for n*n board
{
if(board[i]==j)
printf("\tQ"); //Queen at i,j position
else
printf("\t-"); //empty slot
}
}
/*This function is for checking for the conflicts.If there is no conflict for the desired position
it returns 1 otherwise it returns 0*/
int place(int row ,int column)
{
int i;
for(i=1;i<=row-1;i++)
{
//checking for column and diagonal
conflicts if(board[i]==column)
return 0;
else
55
if(abs(board[i]-column)==abs(i-row))
56
return 0;
}
//no conflicts hence Queen can be
placedreturn 1;
}
/*By this function we try the next free slot and check for proper positioning
of queen */void queen(int row, int n)
{
int column;
for(column=1;column<=n;column
++)
{
if(place(row,column))
{
board[row]=column; //no conflicts so place
queenif(row==n)//dead end
print_board(n); //printing the board configuration
}
else //try queen with next
positionqueen(row+1,n);
}
}
44
11. 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 non graph sheet. The elements can be read from a file or
can be generated using the random number generator. Demonstrate using Java how the
divide and- conquer method works along with its time complexity analysis: worst case,
average case and best case.
import java.util.Random;
import java.util.Scanner;
class QuickSort {
static int comparisons = 0;
static int[] arr;
static void quickSort(int low, int high) {
if (low < high) {
comparisons += 1;
int j = partition(low, high);
quickSort(low, j - 1);
quickSort(j + 1, high);
}
}
static int partition(int low, int high) {
int pivot = arr[low];
int i = low, j = high;
while (i < j) {
comparisons += 1;
while (i < high && arr[i] <= pivot) {
comparisons += 2;
i = i + 1;
}
while (j > low && arr[j] >= pivot) {
comparisons += 2;
j = j - 1;
}
if (i < j) {
comparisons += 1;
interchange(i, j);
}
}
arr[low] = arr[j];
arr[j] = pivot;
return j;
}
static void interchange(int i, int j) {
int temp = arr[i];
arr[i] = arr[j]; 45
arr[j] = temp;
}
public static void main(String[] args) {
int n;
Scanner scanner = new Scanner(System.in);
System.out.print("Enter value of n: ");
n = scanner.nextInt();
arr = new int[n];
System.out.println("Quick Sort");
System.out.println("1. Best/Average Case");
System.out.println("2. Worst Case");
int ch = scanner.nextInt();
switch (ch) {
case 1:
Random random = new Random(3000);
for (int i = 0; i < n; i++) {
arr[i] = random.nextInt();
}
break;
case 2:
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
break;
}
long start = System.nanoTime();
quickSort(0, n - 1);
long end = System.nanoTime();
System.out.println("Sorted Array");
for (int i = 0; i < n; i++) {
System.out.println(arr[i]);
}
System.out.println("Time taken: " + (end - start));
System.out.println("Comparisons: " + comparisons);
}
}
Output:
N=5001
Average and Best Case:
46
Time taken: 3128299
Comparisons: 170690
Worst Case
N=5001
12. 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 non graph sheet. The elements can be read from a file or can be generated using the
random number generator. Demonstrate how the divide and- conquer method works along with its
time complexity analysis: worst case, average case and best case.
import java.util.Random;
import java.util.Scanner;
public class MergeSort
{
public static void main(String[] args)
{
int a[]= new int[100000];
Scanner in = new Scanner(System.in);
long start, end;
System.out.print("Enter the number of elements to be sorted: ");
int n = in.nextInt();
Random rand= new Random();
for(int i=0;i<n;i++)
a[i]=rand.nextInt(2000);
System.out.println("Array elements to be sorted
are:"); for(int i=0; i<n; i++)
System.out.println(a[i]);
start=System.nanoTime();
mergesort(a,0,n-1);
end=System.nanoTime();
47
System.out.println("\nThe sorted elements are: ");
for(int i=0; i<n; i++)
System.out.println(a[i]);
System.out.println("\nThe time taken to sort is "+(end-start)+"ns");
}
static void mergesort(int a[], int low, int high)
{
int mid;
if(low < high)
{
mid = (low+high)/2;
mergesort(a, low, mid);
mergesort(a, mid+1, high);
merge(a, low, mid, high);
}
}
static void merge(int a[], int low, int mid, int high)
{
int i, j, h, k, b[]= new int[100000];
h=low; i=low; j=mid+1;
while((h<=mid) && (j<=high))
{
if(a[h] < a[j])
{
b[i]=a[h];
h=h+1;
}
else
{
b[i] = a[j];
j=j+1;
}
i = i+1;
}
if(h > mid)
{
for(k=j; k<=high; k++)
{
b[i]=a[k];
i= i+1;
}
}
else
{
for(k=h;k<=mid;k++)
48
{
b[i]=a[k];
i= i+1;
}
}
for(k=low; k<= high; k++)
a[k] = b[k];
}
}
Output
Value of n = 5100
Random 5100 numbers will be generated
49
50
13.a) 0/1 Knapsack problem using Greedy Method
import java.util.Scanner;
public class Knap2
{
public static void main(String[] args)
{
int i,j=0,max_qty,m,n;
51
float sum=0,max;
Scanner sc = new Scanner(System.in);
int array[][]=new int[2][20];
System.out.print("Enter no of items: ");
n=sc.nextInt();
System.out.println("Enter the weights of each items:");
for(i=0;i<n;i++)
array[0][i]=sc.nextInt();
System.out.println("Enter the values of each items:");
for(i=0;i<n;i++)
array[1][i]=sc.nextInt();
System.out.println("Enter maximum volume of knapsack :");
max_qty=sc.nextInt();
m=max_qty;
while(m>=0)
{
max=0;
for(i=0;i<n;i++)
{
if(((float)array[1][i])/((float)array[0][i])>max)
{
max=((float)array[1][i])/((float)array[0][i]);
j=i;
}
}
if(array[0][j]>m)
{
System.out.println("Quantity of item number: "+ (j+1) + " added is " +m);
sum+=m*max;
m=-1;
}
else
{
System.out.println("Quantity of item number: " + (j+1) + " added is " + array[0][j]);
m-=array[0][j];
sum+=(float)array[1][j];
array[1][j]=0;
}
}
System.out.println("The total profit is " + sum);
sc.close();
}
}
Output
52
13. b) 0/1 Knapsack problem using Dynamic Programming Method
import java.util.Scanner;
public class Knap1
{
static int max(int a, int b)
{
return (a > b)? a : b;
}
static int knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int [][]K = new int[n+1][W+1];
for (i = 0; i <= n; i++)
{
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];
}
public static void main(String args[])
{
53
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of items: ");
int n = sc.nextInt();
System.out.println("Enter the items weights: ");
int []wt = new int[n];
for(int i=0; i<n; i++)
wt[i] = sc.nextInt();
System.out.println("Enter the items values: ");
int []val = new int[n];
for(int i=0; i<n; i++)
val[i] = sc.nextInt();
System.out.println("Enter the maximum capacity: ");
int W = sc.nextInt();
System.out.println("The maximum value that can be put in a knapsack of capacity W is: " +
knapSack(W, wt, val, n));
sc.close();
}
}
14
From a given vertex in a weighted connected graph, find shortest paths to other vertices
using Dijkstra’s algorithm.
ALGO- Let the node at which we are starting at be called the initial node. Let the distance of
node Y be the distance from the initial node to Y. Dijkstra's algorithm will initially start with infinite
distances and will try to improve them step by step.
54
1. Mark all nodes unvisited. Create a set of all the unvisited nodes called the unvisited set.
2. Assign to every node a tentative distance value: set it to zero for our initial node and
to infinity for all other nodes. Set the initial node as current.[15]
3. For the current node, consider all of its unvisited neighbours and calculate
their tentative distances[Note 1] through the current node. Compare the newly
calculated tentative distance to the current assigned value and assign the smaller one. For
example, if the current node A is marked with a distance of 6, and the edge connecting it
with a neighbour B has length 2, then the distance to B through A will be 6 + 2 = 8. If B
was previously marked with a distance greater than 8 then change it to 8. Otherwise, the
current value will be kept.
4. When we are done considering all of the unvisited neighbours of the current node, mark
the current node as visited and remove it from the unvisited set. A visited node will never
be checked again.
5. If the destination node has been marked visited (when planning a route between two
specific nodes) or if the smallest tentative distance among the nodes in the unvisited set is
infinity (when planning a complete traversal; occurs when there is no connection
between the initial node and remaining unvisited nodes), then stop. The algorithm has
finished.
6. Otherwise, select the unvisited node that is marked with the smallest tentative distance,
set it as the new "current node", and go back to step 3.
When planning a route, it is actually not necessary to wait until the destination node is "visited" as
above: the algorithm can stop once the destination node has the smallest tentative distance among
all "unvisited" nodes (and thus could be selected as the next "current").
#include<stdio.h>
#include<conio.h>
#define infinity
999
int i,u,count,w,flag[10],min;
for(i=1;i<=n;i++)
flag[i]=0,dist[i]=cost[v][i];
count=2;
55
while(count<=n)
56
min=99;
for(w=1;w<=n;w++)
if(dist[w]<min && !
flag[w])
min=dist[w],u=w;
flag[u]=1;
count++;
for(w=1;w<=n;w++)
if((dist[u]+cost[u][w]<dist[w]) && !
flag[w]) dist[w]=dist[u]+cost[u][w];
void main()
int n,v,i,j,cost[10][10],dist[10];
clrscr();
scanf("%d",&n);
n"); for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&cost[i][j]);
if(cost[i][j]==0)
57
cost[i][j]=infinity;
58
}
matrix:"); scanf("%d",&v);
dij(n,v,cost,dist);
n"); for(i=1;i<=n;i++)
if(i!=v)
printf("%d->%d,cost=%d\n",v,i,dist[i]);
getch();
Sample Output:
59
15
Aim- Find Minimum Cost Spanning Tree of a given connected undirected graph using Kruskal's
algorithm. Use Union-Find algorithms in your program
1. Begin
2. Create the edge list of given graph, with their weights.
3. Sort the edge list according to their weights in ascending order.
4. Draw all the nodes to create skeleton for spanning tree.
5. Pick up the edge at the top of the edge list (i.e. edge with minimum weight).
6. Remove this edge from the edge list.
7. Connect the vertices in the skeleton with given edge. If by connecting the vertices, a cycle
is created in the skeleton, then discard this edge.
8. Repeat steps 5 to 7, until n-1 edges are added or list of edges is over.
9. Return
Pseudocode- #include<stdio.h>
#define MAX 30
edgelist elist;
int G[MAX][MAX],n;
edgelist spanlist;
void kruskal();
int find(int belongs[],int vertexno);
void union1(int belongs[],int c1,int c2);
void sort();
void print();
void main()
{
int i,j,total_cost;
printf("\nEnter number of vertices:");
scanf("%d",&n);
60
printf("\nEnter the adjacency matrix:\n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&G[i][j]);
kruskal();
print();
}
void kruskal()
{
int belongs[MAX],i,j,cno1,cno2;
elist.n=0;
for(i=1;i<n;i++)
for(j=0;j<i;j++)
{ if(G[i][j]!
=0)
{
elist.data[elist.n].u=i;
elist.data[elist.n].v=j;
elist.data[elist.n].w=G[i][j];
elist.n++;
}
}
sort(); for(i=0;i<n;i+
+) belongs[i]=i;
spanlist.n=0;
for(i=0;i<elist.n;i++)
{
cno1=find(belongs,elist.data[i].u);
cno2=find(belongs,elist.data[i].v);
if(cno1!=cno2)
{
spanlist.data[spanlist.n]=elist.data[i];
spanlist.n=spanlist.n+1;
union1(belongs,cno1,cno2);
}
}
}
61
}
void sort()
{
int i,j;
edge temp;
for(i=1;i<elist.n;i++)
for(j=0;j<elist.n-1;j++)
if(elist.data[j].w>elist.data[j+1].w)
{
temp=elist.data[j];
elist.data[j]=elist.data[j+1];
elist.data[j+1]=temp;
}
}
void print()
{
int i,cost=0;
for(i=0;i<spanlist.n;i++)
{
printf("\n%d\t%d\t%d",spanlist.data[i].u,spanlist.data[i].v,spanlist.data[i].w);
cost=cost+spanlist.data[i].w;
}
62
16
Aim- . Find Minimum Cost Spanning Tree of a given undirected graph using Prim’s algorithm.
Pseudocode- #include<stdio.h>
#include<conio.h>
int a,b,u,v,n,i,j,ne=1;
int visited[10]= { 0},min,mincost=0,cost[10][10];
void main() {
clrscr();
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");
63
while(ne<n) {
for (i=1,min=999;i<=n;i++)
for (j=1;j<=n;j++)
if(cost[i][j]<min)
if(visited[i]!=0) {
min=cost[i][j];
a=u=i;
b=v=j;
}
if(visited[u]==0 || visited[v]==0)
{
printf("\n Edge %d:(%d %d) cost:%d",ne++,a,b,min);
mincost+=min;
visited[b]=1;
}
cost[a][b]=cost[b][a]=999;
}
printf("\n Minimun cost=%d",mincost);
getch();
}
Output
Example:
Input:
graph[][] = { {0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0} }
which represents the following graph
10
(0)------->(3)
| /|\
5| |
| |1
\|/ |
(1)------->(2)
3
Note that the value of graph[i][j] is 0 if i is equal to j
And graph[i][j] is INF (infinite) if there is no edge from vertex i to j.
Output:
Shortest distance matrix
0 5 8 9
INF 0 3 4
INF INF 0 1
INF INF INF 0
Floyd Warshall Algorithm
We initialize the solution matrix same as the input graph matrix as a first step. Then we update
the solution matrix by considering all vertices as an intermediate vertex. The idea is to one by
one pick all vertices and updates all shortest paths which include the picked vertex as an
intermediate vertex in the shortest path. When we pick vertex number k as an intermediate
vertex, we already have considered vertices {0, 1, 2, .. k-1} as intermediate vertices. For every
pair (i, j) of the source and destination vertices respectively, there are two possible cases.
1) k is not an intermediate vertex in shortest path from i to j. We keep the value of dist[i][j] as it
is.
2) k is an intermediate vertex in shortest path from i to j. We update the value of dist[i][j] as
dist[i][k] + dist[k][j] if dist[i][j] > dist[i][k] + dist[k][j]
The following figure shows the above optimal substructure property in the all-pairs shortest path
problem.
For example, consider the graph shown in figure on right side. A TSP tour in the graph is 1 -2-4-
3-1. The cost of the tour is 10+25+30+15 which is 80.
The problem is a famous NP hard problem. There is no polynomial time know solution for this
problem.
Dynamic Programming:
Let the given set of vertices be {1, 2, 3, 4,….n}. Let us consider 1 as starting and ending point
of output. For every other vertex i (other than 1), we find the minimum cost path with 1 as the
starting point, i as the ending point and all vertices appearing exactly once. Let the cost of this
68
path be cost(i), the cost of corresponding Cycle would be cost(i) + dist(i, 1) where dist(i, 1) is
the distance from i to 1. Finally, we return the minimum of all [cost(i) + dist(i, 1)] values. This
looks simple so far. Now the question is how to get cost(i)?
To calculate cost(i) using Dynamic Programming, we need to have some recursive relation in
terms of sub-problems. Let us define a term C(S, i) be the cost of the minimum cost path visiting
each vertex in set S exactly once, starting at 1 and ending at i.
We start with all subsets of size 2 and calculate C(S, i) for all subsets where S is the subset, then
we calculate C(S, i) for all subsets S of size 3 and so on. Note that 1 must be present in every
subset.
If size of S is 2, then S must be {1, i},
C(S, i) = dist(1, i)
Else if size of S is greater than 2.
C(S, i) = min { C(S-{i}, j) + dis(j, i)} where j belongs to S, j != i and j != 1.
Output of Given Graph:
minimum weight Hamiltonian Cycle :
10 + 25 + 30 + 15 := 80
// CPP program to implement traveling salesman
// problem using naive approach.
#include <bits/stdc++.h>
using namespace std;
#define V 4
// update minimum
min_path = min(min_path, current_pathweight);
} while (
next_permutation(vertex.begin(), vertex.end()));
return min_path;
}
// Driver Code
int main()
{
// matrix representation of graph
int graph[][V] = { { 0, 10, 15, 20 },
{ 10, 0, 35, 25 },
{ 15, 35, 0, 30 },
{ 20, 25, 30, 0 } };
int s = 0;
cout << travllingSalesmanProblem(graph, s) << endl;
return 0;
}
18 Design and implement 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. For example, if S ={1, 2, 5, 6,
8} and d= 9, there are two solutions {1,2,6}and {1,8}. Display a suitable message, if the
given problem instance doesn't have a solution.
Sum of Subsets
Subset-Sum Problem is to find a subset of a given set S= {s1, s2… sn} of n positive integers whose
sum is equal to a given positive integer d. It is assumed that the set‟s elements are sorted in
increasing order. The state-space tree can then be constructed as a binary tree and applying
backtracking algorithm, the solutions could be obtained. Some instances of the problem may have
no solutions
Complexity: Subset sum problem solved using backtracking generates at each step maximal two
new subtrees, and the running time of the bounding functions is linear, so the running time is
O(2n).
70
#include<stdio.h>
#include<conio.h>
int s[10],d,n,set[10],count=0;
void display(int);
int flag=0;
void main()
{
int subset(int,int);
int i;
clrscr();
printf("Enter the number of elements in set\n");
scanf("%d",&n);
printf("Enter the set values\n");
for(i=0;i<n;++i)
scanf("%d",&s[i]);
printf("Enter the sum\n");
scanf("%d",&d);
printf("The progrm output is\n");
subset(0,0);
if(flag==0)
printf("there is no solution");
getch();
}
int subset(int sum,int i)
{
if(sum==d)
{
flag=1;
display(count);
return;
}
if(sum>d||i>=n)
return;
else
{
set[count]=s[i];
71
count++;
subset(sum+s[i],i+1);
count--;
subset(sum,i+1);
}
}
void display(int count)
{
int i;
printf("{");
for(i=0;i<count;i++)
printf("%d",set[i]);
printf("}");
}
19. Design and implement to find all Hamiltonian Cycles in a connected undirected Graph G
of n vertices using backtracking principle.
Hamiltonian Path in an undirected graph is a path that visits each vertex exactly once. A
Hamiltonian cycle (or Hamiltonian circuit) is a Hamiltonian Path such that there is an edge (in
the graph) from the last vertex to the first vertex of the Hamiltonian Path. Determine whether a
given graph contains Hamiltonian Cycle or not. If it contains, then prints the path. Following are
the input and output of the required function.
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
vertex in the Hamiltonian Path. The code should also return false if there is no Hamiltonian
Cycle in the graph.
For example, a Hamiltonian Cycle in the following graph is {0, 1, 2, 4, 3, 0}.
(0)--(1)--(2)
| /\ |
| / \ |
|/ \|
(3) (4)
And the following graph doesn’t contain any Hamiltonian Cycle.
(0)--(1)--(2)
72
| /\ |
| / \ |
|/ \|
(3) (4)
Backtracking Algorithm
Create an empty path array and add vertex 0 to it. Add other vertices, starting from the vertex 1.
Before adding a vertex, check for whether it is adjacent to the previously added vertex and not
already added. If we find such a vertex, we add the vertex as part of the solution. If we do not
find a vertex then we return false.
Implementation of Backtracking solution
Following are implementations of the Backtracking solution.
/* C program for solution of Hamiltonian Cycle problem
using backtracking */
#include<stdio.h>
return true;
}
74
/* Let us put vertex 0 as the first vertex in the path. If there is
a Hamiltonian Cycle, then the path can be started from any point
of the cycle as the graph is undirected */
path[0] = 0;
if ( hamCycleUtil(graph, path, 1) == false )
{
printf("\nSolution does not exist");
return false;
}
printSolution(path);
return true;
}
// Let us print the first vertex again to show the complete cycle
printf(" %d ", path[0]);
printf("\n");
}
return 0;
}
76