You are on page 1of 24

LAB MANUAL

Name of Lab: DESIGN AND ANALYSIS OF ALGORITHMS

Subject Code: 06CS09

Branch : Computer Engineering

Year : Third Year (VI Sem)

Faculty Name : S.P. Gehlot


Experiment No. 1: You are standing at a crossing from where there emerge four roads extending to
infinity. Your friend is somewhere on one of the four roads. You do not know on which road he is and
how far he is from you. You have to walk to your friend and the total distance traveled by you must be at
most constant times the actual distance of your friend from you. In terminology of algorithms, you should
traverse O (d) distance, where d is the distance of your friend from you.

Assumptions: everything will be broken down into some unit distance, I'm going to use 1 km, assume
your friend is an integer number of km from your starting position, just for ease of calculations. The
algorithm will work just as well if friend is not an integer number of km from the start.

Objective: You are standing at a crossing from where there emerge four roads extending to infinity. Find
out the friend at traverse O (d) distance.
Tools:
Software required: C/C++ complier
Hardware required: computer system

Algorithm in English:
Choose any path to start with, walk 1 km down this path and then back to start (assuming friend not
found), cycle through the four paths each time walking twice as far down the path as you walked down
the previous path.

Path 1

path2 -------------- path4

path 3

Example, start with path 1, walk 1km out and then come back, walk 2km down path 2 then back, walk 4
km down path 3 then back, 8km for path 4, back to path 1 walk 16km, continue till friend found.

Algorithm : findfriend()

1) Set dist.=1,sum=0,fir=1
2) Print the path and distance from you
3) Repeat steps 4 to 10 while fri=1
4) Repeat for i=1 to 4
5) If path=I and x<=dist then
6) Sum=sum+x
7) Print find the friend at distance sum traverse
8) Set fri=0 and goto step
9) Else sum=sum+2*dist.
End of if
10) Dist=dist.+1
End of for loop
11) Exit

Program code:

#include<stdio.h>
#include<conio.h>
void main()
{
int found_fri=1,i,dist=1,sum=0,x,path; // here x=dist of friend from you and path where friend is find
clrscr();
printf("frind is find at path and distence from u");
scanf("%d%d",&path,&x);
while(found_fri==1)
{
for(i=1;i<=4;i++)
{
if(path==i && x<=dist)
{
sum=sum+x;
printf("friend find at %d path and total dist traveling u=%d",i,sum);
found_fri=0;
break;
}
else
sum=sum+2*dist;
}
dist=dist+1;
}
getch();
}

Input: friend is find at path from u=3,2.

Output
Friend find at 2 path and total dist travelling u=3
Experiment No. 2:- A simple problem on sorted array: Design an O(n)-time algorithm that, given a
real number x and a sorted array S of n numbers, determines whether or not there exist two
elements in S whose sum is exactly x .

Assumptions: Two variables i and j to index the array, i = 0 j = top. If values at i and j add up to x,
then one. Otherwise you move one of them. If i+j < x then you know that you can increment i, no
other value in the array will combine with the current i to make x, since they will all be less than j,
and j already is not big enough. If i+j > x then you can decrement j, every other value is greater
than value at i so and anything else will never combine to x. If i > j, return failure. Not exactly
dynamic programming, but sort of maybe?

Objective: A simple problem on sorted array: Design an O(n)-time algorithm that, given a real
number x and a sorted array S of n numbers, determines whether or not there exist two elements in
S whose sum is exactly x

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm :- sort_array(A[],n,x)
Here A is an array and n is the numbers of elements in array A. x is an integer value.
1) Set sum=0 ,i=1,j=n
2) Repeat step 3 to 9 while i<j then
3) Set sum=a[i]+a[j]
4) If sum=x then
5) Sum=sum+x
6) Sum of two elements ith and jth place equal to x and goto step
7) Else if sum>x then
8) J=j-1
9) Else i=i+1
End of if
End of step 2 loop
10) If i==j then
11) Elements are not found
End of if
12) Exit

Program code:

#include<stdio.h>
#include<conio.h>
void main()
{
int arr[10],i,j,n,sum=0,x;
clrscr();
printf("Enter the no. of Element");
scanf("%d",&n);
printf("Enter array");
for(i=0;i<=n;i++)
{
scanf("%d",&arr[i]);
}
i=0;
j=n-1;
printf("Enter the value of x");
scanf("%d",&x);
while(i<j)
{
sum=arr[i]+arr[j];
if(sum==x)
{
printf("location 1st=%d\n location2nd= %d ",i+1,j+1);
break;
}
else if(sum>x)
{
j=j--;
}
else
{
i=i++;
}
}
if(i==j)
printf("not found");
getch();
}

Input: Enter the no. of Element 10


Enter array 1 2 3 4 5 6 7 8 9 10
Enter the value of x 19

Output
location 1st=9
location2nd= 10
Experiment No. 3:- You are given an array of infinite length containing zeros followed by ones. How
fast can you locate the first one in the array? O(log(n)). The strategy is to increment exponentially until
you find the first one. Then you know finite bounds that contain the first 1.

Assumptions: I then take these bounds and look at the very middle. If the middle is 1 the right bound
becomes the middle, else the left bound becomes the middle. This continues until the difference in
bounds is 1. The program below demonstrates this using a finite array that is treated as an infinite array.
I'm not sure if divide and conquer is appropriate for this problem anymore, feel free to move it.

Objective: Find the first one in an array of infinite containing zeros followed by one in O(log n)
times.

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm:- firstone(a[],n)
Here A is an array and n is the numbers of elements in array A.
1) Set exp=0
2) If A[2exp]=1 then goto step 9 end of if
3) Exp=exp+1
4) Set b1=2exp-1,b2=2exp
5) If b2-b1 >1 thenprint b1 and b2 end of if
6) Set mid =(b1+b2)/2 +b1
7) If A[mid]=0 then b1=mid
8) Else b2=mid
End of if
9) Exit
Program code:

#include <iostream>
#include <math.h>
using namespace std;

int find_one(int *b, int n){ //Pretend the array is infinite in size

int exp="0; while(1){ //Exponentially search for a one


if(b[(int)pow(2,exp)]==1) break;
exp++;
}
//We now know between which two points the first one exists in log(n)
//The search is now between two finite points

int b1="pow(2,exp-1); int b2="pow(2,exp);


//Do a binary search (of sorts) log(n)
int mid;
while(b2-b1>1){
cout<<b1<<":"<<b2<<endl;
mid="(b2-b1)"/2+b1;
if(b[mid]==0) b1="mid; else b2="mid; }
return mid;
}

int main(){
//Make board for testing, pretend it's infinite.
int board[10000];
for(int i="0;" i<1000;i++) board[i]=0;
for(int i="1001;" i<10000;i++) board[i]=1;
cout<<find_one(board,10000)<<endl;
return 0;
}

Input: Enter array 00000000000000000000000011111111111111111111111

Output
Find first one at 25
Experiment No. 4:- Searching for the Celebrity: Celebrity is a person whom everybody knows but
he knows nobody. You have gone to a party. There are total n persons in the party. Your job is to
find the celebrity in the party. You can ask questions of the form Does Mr. X know Mr. Y ?. You will
get a binary answer for each such question asked. Find the celebrity by asking only O(n) questions.

Assumptions: First you assume first one is celebrity and ask question that you know second if he
ask yes then he is not celebrity because celebrity do not knows nobody. And select second and ask
same question for third person and if he ask no then he can be celebrity. This quation put all
persons one by one and at late we find the celebrity.

Objective: find the celebrity in n number of unknown persons in party and ask only O(n) questions.

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm:-
Program code:

#include<stdio.h>
#include<conio.h>
void main()
{
int i,guestq[10],cele,ans1,ans2;
for(i=0;i<10;i++)
{
guestq[i]=i;
}
cele=guestq[0]; //defaulty assume first one is celebrity
for(i=0;i<9;i++)
{
clrscr();
printf("\nCelebrity may be G%d",cele);
//ask from (doubted celebrity) guest first regrding 2nd
printf("\nGuest G%d, Do u knw G%d??",cele,i+1);
printf("\npress \n1.know\n2. dont know:\nEnter the choice: ");
scanf("%d",&ans1);

//ask from guest 2nd regrding 1st


printf("\nGuest G%d, Do u knw G%d??",i+1,cele);
printf("\npress \n1.know\n2. dont know:\nEnter the choice: ");
scanf("%d",&ans2);

//check for conditions

if(ans1==ans2) //for both yes and both no


{
printf("\nG%d and G%d are not celebrity",cele,i+1);
cele=guestq[i+2];
i++;
}
else if(ans1==1 && ans2!=1) //1st knw 2nd but 2nd dont knw 1st
{
cele=guestq[i+1]; //1st cant b cele but 2nd can be
printf("\nG%d cant be a celebrity\nG%d can be a celebrity",cele,i+1);
}
else
{
//2nd cant b cele but 1st can be i.e last fixed cele
printf("\nG%d cant be a celebrity\nG%d can be a celebrity",i+1,cele);
}
}
clrscr();

//print the celebrity id


printf("\ncelebrity is G%d",cele);
getch();
}

OUTPUT :

Celebrity may be G0
Guest G0, Do u knw G1??
press
1.know
2. dont know:
Enter the choice: 1

Guest G1, Do u knw G0??


press
1.know
2. dont know:
Enter the choice: 1

Celebrity may be G2
Guest G2, Do u knw G3??
press
1.know
2. dont know:
Enter the choice: 2
Guest G3, Do u knw G2??
press
1.know
2. dont know:
Enter the choice: 1

Celebrity may be G2
Guest G2, Do u knw G4??
press
1.know
2. dont know:
Enter the choice: 2

Guest G4, Do u knw G2??


press
1.know
2. dont know:
Enter the choice: 1

Celebrity may be G2
Guest G2, Do u knw G5??
press
1.know
2. dont know:
Enter the choice: 1

Guest G5, Do u knw G2??


press
1.know
2. dont know:
Enter the choice: 2

Celebrity may be G5
Guest G5, Do u knw G6??
press
1.know
2. dont know:
Enter the choice: 2

Guest G6, Do u knw G5??


press
1.know
2. dont know:
Enter the choice: 1
Celebrity may be G5
Guest G5, Do u knw G7??
press
1.know
2. dont know:
Enter the choice: 2

Guest G7, Do u knw G5??


press
1.know
2. dont know:
Enter the choice: 1

Celebrity may be G5
Guest G5, Do u knw G8??
press
1.know
2. dont know:
Enter the choice: 2

Guest G8, Do u knw G5??


press
1.know
2. dont know:
Enter the choice: 1

Celebrity may be G5
Guest G5, Do u knw G9??
press
1.know
2. dont know:
Enter the choice: 2

Guest G9, Do u knw G5??


press
1.know
2. dont know:
Enter the choice: 1

celebrity is G5
Experiment No.5:You are given n real numbers in an array. a number in the array is called a decimal
dominant if it occurs more than n/10 times in the array. Give an O(n) time algorithm to determine if the
given array has a decimal dominant.

Assumptions: My solution was to create 9 count variables for different numbers. Each time there is a
unique number it's added to a count variable and every time it's seen after that the associated count
variables counter is incremented. If every count variable is filled a new unique number shows up then 1 is
decremented from each counter. If one approaches 0 then the count variable is wiped and can be filled
with a new unique one. Once this has been finished any count variables with counts greater than 1 have
more than 10 instances of themselves in the list.

Objective: find out decimal dominant,given an O(n) time algorithm.

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm:

//Setup a list for testing, 3 and 5's are dominant


int l[100];
for(int i="0;" i<11;i++) l[i]=3;
for(int i="11;" i<22;i++) l[i]=5;
for(int i="22;" i<100;i++) l[i]=i;

//loop through list 1 time, 0(n)


for(int i="0;" i<100; i++){
bool found="false;//Check if already stored, if so increment
for(int j="0;" j<9; j++){
if(l[i]==n[j]){
c[j]++;
found="true; break;

//If not stored find an empty spot, increment


if(found==false){
for(int j="0;" j<9; j++){
if(n[j]==-1){
n[j]=l[i];
c[j]++;
found="true; break;

//If no empty spot then dump one from each existing bin
if(found==false){
for(int j="0;" j<9; j++){
if(c[j]>1) c[j]--;
if(c[j]==1)
c[j]--;
n[j]=-1;

//All done, show results of bins with 2 or more


for(int j="0;" j<9; j++)
if(c[j]>1) cout<<
return 0;
}

Program code:
#include <stdio.h>
#include<conio.h>
int main(){
int n[9],c[9]; for(int i="0;" i<9; i++){
n[i]=-1;
c[i]=0;
}
int l[100];
for(int i="0;" i<11;i++) l[i]=3;
for(int i="11;" i<22;i++) l[i]=5;
for(int i="22;" i<100;i++) l[i]=i;
for(int i="0;" i<100; i++){
bool found="false;
for(int j="0;" j<9; j++){
if(l[i]==n[j]){
c[j]++;
found="true; break;
}
}
if(found==false){
for(int j="0;" j<9; j++){
if(n[j]==-1){
n[j]=l[i];
c[j]++;
found="true; break;
}
}
}
if(found==false){
for(int j="0;" j<9; j++){
if(c[j]>1) c[j]--;
if(c[j]==1) {
c[j]--;
n[j]=-1;
}
}
}
}

for(int j="0;" j<9; j++){


if(c[j]>1) cout<<
}
return 0;
}

Input:
0,1,2,3,4,5,6,7,8,9,9,9,9,9,9,9,9,9,9,9,9,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,55,5,5,5,5,5,5,5,5,5,5,5,5
Output:3,5
Experiment No. 6 :- Consider a binary heap containing n numbers (the root stores the greatest number).
You are given a positive integer k < n and a number x . You have to determine whether the k th largest
element of the heap is greater than x or not. Your algorithm must take O(k) time. You may use O(k) extra
storage.

Assumptions: I think you are trying to find the kth largest element in the heap in O(k) time in order to
solve this problem. But actually, you need not find the kth largest element in the heap to solve this
problem. You will be able to solve the problem if you are able to find whether the number of elements in
the heap which are greater than x are more/less/equal to k . Now exploit the definition of the heap, to do
this task in O(k) time. Note that you have extra O(k) storage space to use.

Objective: Find out kth largest element of the heap is greater than x or not and youmay use O(k) extra
storage.

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm:

Program code:

GTX(x,k){
array Q;
stack K; //has capacity k
index i= 1;
int count;
int top;
for (i=1;i<=3,i++){
if (x<Q[i]) then
K.push(Q[i]); count++;}
while (K.pop() is valid && count<k){
top=K.pop();
if (x<Q[top/2]) then //explore children of smallest number >x
K.push(top/2);
count++;
if (x<Q[top/2+1]) then
K.push(top/2+1);
count++;}
if (K.empty()) && (count<k) then
return false;
elseif (K.empty() && count=k) then
return true;
else
GTX(x,k){
array Q;
stack K; //has capacity k
index i= 1;
int count;
int top;
for (i=1;i<=3,i++){
if (x<Q[i]) then
K.push(Q[i]); count++;}
while (K.pop() is valid && count<k){
top=K.pop();
if (x<Q[top/2]) then //explore children of smallest number >x
K.push(top/2);
count++;
if (x<Q[top/2+1]) then
K.push(top/2+1);
count++;}
if (K.empty()) && (count<k) then
return false;
elseif (K.empty() && count=k) then
return true;
else
return true;
}
return true;
}

Time complexity: The stack has maximum capacity of k, which uses our O(k) storage space. If x is less
than a node we explore its children and stick them in the stack. As we explore children we delete parents
from the stack, but keep track if more than k elements are pushed into the stack with count. The while
loop will execute at most k times.
Experiment No. 6 :- Merging two search trees : You are given two height balanced binary search trees
T and T', storing m and n elements respectively. Every element of tree T is smaller than every element of
tree T'. Every node u also stores height of the subtree rooted at it. Using this extra information how can
you merge the two trees in time O(log m + log n) (preserving both the height balance and the order)?

Assumptions: Solve this problem we use height balances tree 2-3 tree . first we make the inoder travels
of both tree and merge both list and make 2-3 tree from merging both list.

Objective: Merging two search trees in time O(log m + log n).

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm:

Program code:

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#define NL printf("\n")
typedef struct node *np;
np memalloc();
np create_newnode(int);
np create();
void inorder(np);
int insert(np,int);
void fre(np root);
int getvalue();
int leaf(np);
np search(np,int);
void merge(np, np);

struct node
{
int key;
np left;
np right;
};

void main()
{
np tree1,tree2;
int num;
char ans='y';
printf("Cereating first tree.....\n");
tree1=create();
while(ans=='y'||ans=='Y')
{
printf("Enter a number : ");
num=getvalue();
insert(tree1,num);
printf("Have more numbers? ");
fflush(stdin);
ans=getch();
}
printf("Inorder traversal of this tree is:\n");
inorder(tree1);
printf("Cereating second tree.....\n");
tree2=create();
while(ans=='y'||ans=='Y')
{
printf("Enter a number : ");
num=getvalue();
insert(tree2,num);
printf("Have more numbers? ");
fflush(stdin);
ans=getch();
}
printf("Inorder traversal of this tree is:\n");
inorder(tree2);
printf("Merging the two trees......\n");
merge(tree1,tree2);
printf("Inorder traversal of tree1 is .........\n");
inorder(tree1);
fre(tree1);
}

void merge(np tree1, np tree2)


{
if(tree2)
{
inorder(tree2->left);
inorder(tree2->right);
insert(tree1,tree2->key);
fre(tree2);
}
}

np create()
{
int num;
clrscr();
printf("\nEnter number\t");
num=getvalue();
return(create_newnode(num));
}

np memalloc()
{
np n;
if((n=(np)malloc(sizeof (struct node)))==NULL)
{
printf("\nMemory full\n");
exit(1);
return(n);
}
else
return(n);
}

np create_newnode(int num)
{
np new_node;
new_node=memalloc();
new_node->left=new_node->right=NULL;
new_node->key=num;
return(new_node);
}

void inorder(np root)


{
if(root)
{
inorder(root->left);
printf("\t%d",root->key); /* LEFT,NODE,RIGHT */
inorder(root->right);
}
}

void fre(np root)


{
if(root)
{
fre(root->left);
fre(root->right);
free(root); /* LEFT,RIGHT,NODE */
}
}

int insert(np root,int num)


{
int rval;
while(1)
{
if(root->key==num)
{
rval=0;
printf("\nDuplication is not possible in the binary search tree.\n");
break;
}
if(num<root->key)
{
if(root->left!=NULL)
{
root=root->left;
continue;
}
else
{
root->left=create_newnode(num);
rval=1;
break;
}
}
else
{
if(root->right!=NULL)
{
root=root->right;
continue;
}
else
{
root->right=create_newnode(num);
rval=1;
break;
}
}
}
return(rval);
}

int getvalue()
{
int num;
while(!scanf("%d",&num))
{
printf("\nYou should enter a number. Press any key ...");
getch();
fflush(stdin);
}
return(num);
}

int leaf(np node)


{
if(node->left==NULL && node->right==NULL)
return(1);
else
return(0);
}

np search(np root, int num)


{
while(root!=NULL)
if(root->key==num)
break;
else
if(num<root->key)
root=root->left;
else
root=root->right;
return(root);
}

Experiment No. 7:- Shortest Path Problems : From a subset of vertices to another subset of
vertices -Given a directed graph G(V,E), where edges have nonnegative weights. S and D are two
disjoint subsets of the set of vertices. Give an O(|V| log |V| + |E|) time algorithm to find the shortest path
among the set of paths possible from any node in S to any node in D.

Assumptions: Solve this problem we use minimum spanning tree one of both algorithms(kruskal and
prims algorithm).

Objective: Find the shortest path from Given a directed graph G(V,E), where edges have nonnegative
weights

Tools :
Software required: c/c++ complier
Hardware required: computer system

Algorithm:

Program code:
#include "stdio.h"
#include "conio.h"

int n;

int weight[100][100];

char inTree[100];

int d[100];
int whoTo[100];

void updateDistances(int target)


{
int i;
for (i = 0; i < n; ++i)
if ((weight[target][i] != 0) && (d[i] > weight[target][i]))
{
d[i] = weight[target][i];
whoTo[i] = target;
}
}

main() {
FILE *f = fopen("dist.txt", "r");
int i,j,total,treeSize;
fscanf(f, "%d", &n);
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
fscanf(f, "%d", &weight[i][j]);
fclose(f);

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


d[i] = 100000;

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


inTree[i] = 0;

printf("Adding node %c\n", 0 + 'A');


inTree[0] = 1;
updateDistances(0);
total = 0;
for (treeSize = 1; treeSize < n; ++treeSize)
{
int min = -1;
for (i = 0; i < n; ++i)
if (!inTree[i])
if ((min == -1) || (d[min] > d[i]))
min = i;
printf("Adding edge %c-%c\n", whoTo[min] + 'A', min + 'A');
inTree[min] = 1;
total += d[min];

updateDistances(min);
}

printf("Total distance: %d\n", total);

return 0;
}

You might also like