0% found this document useful (0 votes)
45 views30 pages

Daa Practical 1 To 8

project ppt

Uploaded by

Ganesh Dhimrekar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
45 views30 pages

Daa Practical 1 To 8

project ppt

Uploaded by

Ganesh Dhimrekar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 30

H.V.P.

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:

Professor – in – charge H.O.D


(Dept. of CSE

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)

Worst Case Time Complexity: O(n*log n)

Average 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.

1. Always pick first element as pivot.


2. Always pick last element as pivot (implemented below)
3. Pick a random element as pivot.
4. Pick median as pivot.
The key process in quickSort is partition(). Target of partitions is, given an array and an
element x of array as pivot, put x at its correct position in sorted array and put all smaller
elements (smaller than x) before x, and put all greater elements (greater than x) after x.
All this should be done in linear time.

Algorithm:-
PARTITION (array A, start, end)
{

1 pivot ? A[end]

2 i ? start-1

3 for j ? start to end -1 {

4 do if (A[j] < pivot) {

5 then i ? i + 1

6 swap A[i] with A[j]

7 }}

8 swap A[i+1] with A[end]

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)

Result:- Thus I have executed the C program code of sorting of


array using quick sort.

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

int a[11] = { 34,78,12,90,56,78,23,66,12,21,20 };


int b[10];

void merging(int low, int mid, int high) {


int l1, l2, i;

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++];
}

while(l1 <= mid)


b[i++] = a[l1++];

while(l2 <= high)


b[i++] = a[l2++];

for(i = low; i <= high; i++)


a[i] = b[i];
}

void sort(int low, int high) {


int mid;

if(low < high) {


mid = (low + high) / 2;
sort(low, mid);
sort(mid+1, high);
merging(low, mid, high);
} else {
return;
}
}

int main() {
int i;

printf("List before sorting\n");

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


printf("%d ", a[i]);

sort(0, max);

printf("\nList after sorting\n");

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


printf("%d ", a[i]);
}
Output:-

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:-

Minimum Spanning Tree:


A spanning tree of that graph is a subgraph that is a tree and connects all the vertices
together. A single graph can have many different spanning trees. A minimum spanning
tree (MST) or minimum weight spanning tree for a weighted, connected, undirected
graph is a spanning tree with a weight less than or equal to the weight of every other
spanning tree. The weight of a spanning tree is the sum of weights given to each edge
of the spanning tree.

A minimum spanning tree has (V – 1) edges where V is the number of vertices in the
given graph.

The steps for finding MST using Kruskal’s algorithm:

1. Sort all the edges in non-decreasing order of their weight.

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.

3. Repeat until there are (V-1) edges in the spanning tree.

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

typedef struct edge


{
int u,v,w;
}edge;

typedef struct edgelist


{
edge data[MAX];
int n;
}edgelist;

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);
}
}
}

int find(int belongs[],int vertexno)


{
return(belongs[vertexno]);
}

void union1(int belongs[],int c1,int c2)


{
int i;
for(i=0;i<n;i++)
if(belongs[i]==c2)
belongs[i]=c1;
}

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;
}

printf("\n\nCost of the spanning tree=%d",cost);


}
Output:-

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).

Let us understand LCS with an example.

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}, ...

Among these subsequences, {C, D, A, C} is the longest common subsequence. We are


going to find this longest common subsequence using dynamic programming.

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 print(int i,int j)


{
if(i==0 || j==0)
return;
if(b[i][j]=='c')
{
print(i-1,j-1);
printf("%c",x[i-1]);
}
else if(b[i][j]=='u')
print(i-1,j);
else
print(i,j-1);
}

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;

//c, u and l denotes cross, upward and downward directions respectively


for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
{
if(x[i-1]==y[j-1])
{
c[i][j]=c[i-1][j-1]+1;
b[i][j]='c';
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i][j]='u';
}
else
{
c[i][j]=c[i][j-1];
b[i][j]='l';
}
}
}
int main()
{
printf("Enter 1st sequence:");
scanf("%s",x);
printf("Enter 2nd sequence:");
scanf("%s",y);
printf("\nThe Longest Common Subsequence is ");
lcs();
print(m,n);
return 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);

printf(" - N Queens Problem Using Backtracking -");


printf("\n\nEnter number of Queens:");
scanf("%d",&n);
queen(1,n);
return 0;
}

//function for printing the solution


void print(int n)
{
int i,j;
printf("\n\nSolution %d:\n\n",++count);

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
}
}
}

/*funtion to check conflicts


If no conflict for desired postion returns 1 otherwise returns 0*/
int place(int row,int column)
{
int i;
for(i=1;i<=row-1;++i)
{
//checking column and digonal conflicts
if(board[i]==column)
return 0;
else
if(abs(board[i]-column)==abs(i-row))
return 0;
}

return 1; //no conflicts


}

//function to 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 queen
if(row==n) //dead end
print(n); //printing the board configuration
else //try queen with next position
queen(row+1,n);
}
}
}
Output:-

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:
GDHBEACF
In the case of pre-order traversal, we visit the root node first. Hence the pre-order
traversal of this tree would be:
ABDGHECF
In the post-order traversal, we traverse the root node at the end. Therefore the post-
order traversal of this tree would be:
GHDEFCA
Algorithm:-

Inorder

Until all nodes are traversed −


Step 1 − Recursively traverse left subtree.
Step 2 − Visit root node.
Step 3 − Recursively traverse right subtree.

Preorder

Until all nodes are traversed −


Step 1 − Visit root node.
Step 2 − Recursively traverse left subtree.
Step 3 − Recursively traverse right subtree.

Postorder

Until all nodes are traversed −


Step 1 − Recursively traverse left subtree.
Step 2 − Recursively traverse right subtree.
Step 3 − Visit root node.

Program Code:-
// C program for different tree traversals
#include <stdio.h>
#include <stdlib.h>

/* A binary tree node has data, pointer to left child


and a pointer to right child */
struct node
{
int data;
struct node* left;
struct node* right;
};

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;

return(node);
}

/* Given a binary tree, print its nodes according to the


"bottom-up" postorder traversal. */
void printPostorder(struct node* node)
{
if (node == NULL)
return;

// first recur on left subtree


printPostorder(node->left);

// then recur on right subtree


printPostorder(node->right);

// now deal with the node


printf("%d ", node->data);
}

/* Given a binary tree, print its nodes in inorder*/


void printInorder(struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder(node->left);

/* then print the data of node */


printf("%d ", node->data);

/* now recur on right child */


printInorder(node->right);
}

/* Given a binary tree, print its nodes in preorder*/


void printPreorder(struct node* node)
{
if (node == NULL)
return;

/* first print data of node */


printf("%d ", node->data);

/* then recur on left sutree */


printPreorder(node->left);

/* now recur on right subtree */


printPreorder(node->right);
}

/* Driver program to test above functions*/


int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);

printf("Preorder traversal of binary tree is: ");


printPreorder(root);

printf("\nInorder traversal of binary tree is: ");


printInorder(root);

printf("\nPostorder traversal of binary tree is: ");


printPostorder(root);

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.

Lets take an example,

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;

// Initialize all occurrences as -1


for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;

// Fill the actual value of last occurrence of a character


for (i = 0; i < size; i++)
badchar[(int) str[i]] = i;
}
void search( char *txt, char *pat)
{
int m = strlen(pat);
int n = strlen(txt);

int badchar[NO_OF_CHARS];
badCharHeuristic(pat, m, badchar);

int s = 0; // s is shift of the pattern with respect to text


while(s <= (n - m))
{
int j = m-1;
while(j >= 0 && pat[j] == txt[s+j])
j--;

/* If the pattern is present at current shift, then index j


will become -1 after the above loop */
if (j < 0)
{
printf("\n pattern occurs at shift = %d", s);

s += (s+m < n)? m-badchar[txt[s+m]] : 1;

else
s += max(1, j - badchar[txt[s+j]]);
}
}

/* Driver program to test above funtion */


int main()
{
char txt[] = "ABCBBCABCAAAABCBCABCAABCACBACBACABBA";
char pat[] = "ABC";
search(txt, pat);
return 0;
}
Output:-

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.

You might also like