Daa Practical 1 To 8
Daa Practical 1 To 8
Mandal’s
College of Engineering And Technology Amravati.
Certificate
This is to certify, that Shri. /Kumari Rahul.Ramesh.Deshmukh
Roll No. 44 Studying in 3rd Year CSE
In the year 2021 – 2022 is a bonafide Student of this Institution
and has completed practical work in subject Design & Analysis of
Algo.
Based on the syllabus successfully & submitted this report
containing a record of the practical work.
Date:
Practical No.1
Aim:- Impliment a C program to perform recursive calls using the linear search
algorithm when the list is given.
Theory:-
Linear Search:- A linear search is the simplest method of searching a data set. Starting at the
beginning of the data set, each item of data is examined until a match is made. Once the item is
found, the search ends. If there is no match, the algorithm must deal with this.
Recursion:- Recursion is the process which comes into existence when a function calls a copy
of itself to work on a smaller problem. Any function which calls itself is called recursive
function, and such function calls are called recursive calls. Recursion involves several
numbers of recursive calls.
ALGORITHM:-
Set j to 1.
If j > n, jump to step 7.
If X[j] == i, jump to step 6.
Then, increment j by 1 i.e. j = j+1.
Go back to step 2.
Display the element i which is found at particular index i, then jump to step 8.
Display element not found in the set of input elements.
Exit/End.
PROGRAMMING CODE:-
#include <stdio.h>
int RecursiveLS(int arr[], int value, int index, int n)
{
int pos = 0;
if(index >= n)
{
return 0;
}
else if (arr[index] == value)
{
pos = index + 1;
return pos;
}
else
{
return RecursiveLS(arr, value, index+1, n);
}
return pos;
}
int main()
{
int n, value, pos, m = 0, arr[100];
printf("Enter the total elements in the array ");
scanf("%d", &n);
printf("Enter the array elements\n");
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
printf("Enter the element to search ");
scanf("%d", &value);
pos = RecursiveLS(arr, value, 0, n);
if (pos != 0)
{
printf("Element found at pos %d ", pos);
}
else
{
printf("Element not found");
}
return 0;
}
OUTPUT:-
COMPLEXITY:-
Best Case Time Complexity: O(n*log n)
Result:- In this way I have perform recursive calls using linear search algorithm.
Practical No. 2
Aim:- Implement a C program to sort an array of integers using quick sort.
Theory:-
Quick Sort:
Quick Sort is a Divide and Conquer algorithm. It picks an element as pivot and partitions
the given array around the picked pivot. There are many different versions of quickSort
that pick pivot in different ways.
Algorithm:-
PARTITION (array A, start, end)
{
1 pivot ? A[end]
2 i ? start-1
5 then i ? i + 1
7 }}
9 return i+1
Program code:-
#include<stdio.h>
void quicksort(int number[25],int first,int last){
int i, j, pivot, temp;
if(first<last){
pivot=first;
i=first;
j=last;
while(i<j){
while(number[i]<=number[pivot]&&i<last)
i++;
while(number[j]>number[pivot])
j--;
if(i<j){
temp=number[i];
number[i]=number[j];
number[j]=temp;
}
}
temp=number[pivot];
number[pivot]=number[j];
number[j]=temp;
quicksort(number,first,j-1);
quicksort(number,j+1,last);
}
}
int main(){
int i, count, number[25];
printf("How many elements are u going to enter: ");
scanf("%d",&count);
printf("Enter %d elements: ", count);
for(i=0;i<count;i++)
scanf("%d",&number[i]);
quicksort(number,0,count-1);
printf("Order of Sorted elements: ");
for(i=0;i<count;i++)
printf(" %d",number[i]);
return 0;
}
Output:-
Complexity:-
Best case O(n*logn)
Average case O(n*logn)
Worst case O(n2)
Practical No. 3
Aim:- Implement the divide and conquer Strategy using merge sort Algorithm and
determine the complexity of an algorithm when the list is given.
Theory:-
Merge sort:
Merge Sort is a Divide and Conquer algorithm. It divides the input array into two halves,
calls itself for the two halves, and then it merges the two sorted halves. The merge()
function is used for merging two halves. The merge(arr, l, m, r) is a key process that
assumes that arr[l..m] and arr[m+1..r] are sorted and merges the two sorted sub-arrays
into one.
Algorithm:-
MergeSort(A, p, r):
1. if p > r
2. return
3. q = (p+r)/2
4. mergeSort(A, p, q)
5. mergeSort(A, q+1, r)
6. merge(A, p, q, r)
Program code:-
#include <stdio.h>
#define max 10
for(l1 = low, l2 = mid + 1, i = low; l1 <= mid && l2 <= high; i++) {
if(a[l1] <= a[l2])
b[i] = a[l1++];
else
b[i] = a[l2++];
}
int main() {
int i;
sort(0, max);
Complexity:-
Best case O(n*log n)
Average case O(n*log n)
Worst case O(n*log n)
Result:- Thus I have executed the C program code for merge sort.
Practical No. 4
Aim:- Implement a C program to find minimum cost Spanning tree of a given
undirected graph using Kruskal’s algorithm.
Theory:-
A minimum spanning tree has (V – 1) edges where V is the number of vertices in the
given graph.
2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far.
If cycle is not formed, include this edge. Else, discard it.
Algorithm:-
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
Program Code:-
#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);
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);
}
}
}
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;
}
Complexity:-
Best Case O(E log V)
Average Case O(E log V)
Worst Case O(E log V)
*Where V is Number of vertices.
Result:- Thus I have executed the C program to find minimum cost Spanning tree of a
given undirected graph using Kruskal’s algorithm.
Practical No. 5
Aim:- Implement a C program for Longest common subsequence (LCS) problem
using Dynamic Programming.
Theory:-
The longest common subsequence (LCS) is defined as the longest subsequence that is
common to all the given sequences, provided that the elements of the subsequence are
not required to occupy consecutive positions within the original sequences.
If S1 and S2 are the two given sequences then, Z is the common subsequence of S1
and S2 if Z is a subsequence of both S1 and S2. Furthermore, Z must be a strictly
increasing sequence of the indices of both S1 and S2.
In a strictly increasing sequence, the indices of the elements chosen from the original
sequences must be in ascending order in Z.
If
S1 = {B, C, D, A, A, C, D}
Then, {A, D, B} cannot be a subsequence of S1 as the order of the elements is not the
same (ie. not strictly increasing sequence).
If
S1 = {B, C, D, A, A, C, D}
S2 = {A, C, D, B, A, C}
Then, common subsequences are {B, C}, {C, D, A, C}, {D, A, C}, {A, A, C}, {A, C}, {C,
D}, ...
Algorithm:-
1. Suppose X and Y are the two given sequences
2. Initialize a table of LCS having a dimension of X.length * Y.length
3. XX.label = X
4. YY.label = Y
5. LCS[0][] = 0
6. LCS[][0] = 0
7. Loop starts from the LCS[1][1]
8. Now we will compare X[i] and Y[j]
9. if X[i] is equal to Y[j] then
10. LCS[i][j] = 1 + LCS[i-1][j-1]
11. Point an arrow LCS[i][j]
12. Else
13. LCS[i][j] = max(LCS[i-1][j], LCS[i][j-1])
Program code:-
#include<stdio.h>
#include<string.h>
int i,j,m,n,c[20][20];
char x[20],y[20],b[20][20];
void lcs()
{
m=strlen(x);
n=strlen(y);
for(i=0;i<=m;i++)
c[i][0]=0;
for(i=0;i<=n;i++)
c[0][i]=0;
Output:-
Complexity:-
Best Case O(n*m)
Average Case O(n*m)
Worst Case O(n*m)
Result:- Thus I have executed the C program for Longest common subsequence
(LCS) problem using Dynamic Programming.
Practical No. 6
Aim:- Implement a C program to find the solution for n-queen problem using
backtracking.
Theory:-
N-Queen Problem:
The N Queen is the problem of placing N chess queens on an N×N chessboard so that
no two queens attack each other. For example, following is a solution for 4 Queen
problem.
Each solution contains distinct board configurations of the N-queens’ placement, where
the solutions are a permutation of [1,2,3..n] in increasing order, here the number in the
ith place denotes that the ith-column queen is placed in the row with that number. For
the example above solution is written as [[2 4 1 3 ] [3 1 4 2 ]]. The solution discussed
here is an extension of the same approach.
Backtracking Algorithm :
The idea is to place queens one by one in different columns, starting from the leftmost
column. When we place a queen in a column, we check for clashes with already placed
queens. In the current column, if we find a row for which there is no clash, we mark this
row and column as part of the solution. If we do not find such a row due to clashes then
we backtrack and return false.
Algorithm:-
1. N - Queens (k, n)
2. For i ← 1 to n
3. do if Place (k, i) then
4. x [k] ← i;
5. if (k ==n) then
6. write (x [1....n));
7. else
8. N - Queens (k + 1, n);
Program code:-
#include<stdio.h>
#include<math.h>
int board[20],count;
int main()
{
int n,i,j;
void queen(int row,int n);
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 nxn board
{
if(board[i]==j)
printf("\tQ"); //queen at i,j position
else
printf("\t-"); //empty slot
}
}
}
Complexity:-
Best Case O(n^2)
Average Case O(n^2)
Worst Case O(n^2)
Result:- Thus I have executed the C program to find the solution for n-queen problem
using backtracking.
Practical No:-07
Aim:- Implement C program to find Inorder, Preorder and Postorder traversal of tree
using Back Tracking.
Theory:-
Tree Traversal – Inorder , Preorder , Postorder:
Traversing a tree means visiting every node in the tree. You might, for instance, want to
add all the values in the tree or find the largest one. For all these operations, you will
need to visit each node of the tree.
Now we’re taking an example tree, and let’s find the various traversals of the tree:
If we apply in-order traversal in this example tree, the in-order traversal of this tree
would be:
GDHBEACF
In the case of pre-order traversal, we visit the root node first. Hence the pre-order
traversal of this tree would be:
ABDGHECF
In the post-order traversal, we traverse the root node at the end. Therefore the post-
order traversal of this tree would be:
GHDEFCA
Algorithm:-
Inorder
Preorder
Postorder
Program Code:-
// C program for different tree traversals
#include <stdio.h>
#include <stdlib.h>
return(node);
}
getchar();
return 0;
}
Output:-
Complexity:-
Best Case O(n)
Worst Case O(n)
Average Case O(n)
Result:- Thus I have executed the C program for to find Inorder, Preorder and
Postorder traversal of tree using Back Tracking.
Practical No:-08
Aim:- Desing and implement Boyer Moore algorithm for pattern searching.
Theory:-
Boyer Moore Algorithm
Sometimes it is called the Good Suffix Heuristic method. For this case, a
preprocessing table is created as a suffix table. In this procedure, the substring or
pattern is searched from the last character of the pattern. When a substring of the main
string matches with a substring of the pattern, it moves to find other occurrences of the
matched substring. It can also move to find a prefix of the pattern which is a suffix of the
main string. Otherwise, it moves the whole length of the pattern.
Input:
Main String: ABAAABCDBBABCDDEBCABC, Pattern: ABC
Output:
Pattern found at position: 4
Pattern found at position: 10
Pattern found at position: 18
Algorithm:-
BOYER-MOORE-MATCHER (T, P, ∑)
1. n ←length [T]
2. m ←length [P]
3. λ← COMPUTE-LAST-OCCURRENCE-FUNCTION (P, m, ∑ )
4. ɣ← COMPUTE-GOOD-SUFFIX-FUNCTION (P, m)
5. s ←0
6. While s ≤ n - m
7. do j ← m
8. While j > 0 and P [j] = T [s + j]
9. do j ←j-1
10. If j = 0
11. then print "Pattern occurs at shift" s
12. s ← s + ɣ[0]
13. else s ← s + max (ɣ [j], j - λ[T[s+j]])
Code:-
/* Program for Bad Character Heuristic of Boyer Moore String Matching Algorithm */
# include <limits.h>
# include <string.h>
# include <stdio.h>
# define NO_OF_CHARS 256
// A utility function to get maximum of two integers
int max (int a, int b) { return (a > b)? a: b; }
// The preprocessing function for Boyer Moore's bad character heuristic
void badCharHeuristic( char *str, int size, int badchar[NO_OF_CHARS])
{
int i;
int badchar[NO_OF_CHARS];
badCharHeuristic(pat, m, badchar);
else
s += max(1, j - badchar[txt[s+j]]);
}
}
Complexity:-
Best Case Θ (m)+Ω (n/m)
Average Case O(n)
Worst Case O(nm)
Where, where the length of the pattern is m and the length of the search string is n.
Result:-In this practical I have implement Boyer Moore algorithm for pattern searching
in C program.