AEC LAB
AEC LAB
Experiment 1 Date:
Aim: Develop a program and measure the running time for Binary Search with Divide and Conquer.
Description
Binary Search is defined as a searching algorithm used in a sorted array by repeatedly dividing the
search interval in half. The idea of binary search is to use the information that the array is sorted and
reduce the time complexity to O(log N).
Conditions for when to apply Binary Search in a Data Structure:
To apply Binary Search algorithm:
The data structure must be sorted.
Access to any element of the data structure takes constant time.
Binary Search Algorithm:
In this algorithm,
Divide the search space into two halves by finding the middle index “mid”.
Code
#include<stdio.h>
int main()
{
int arr[10],n,se,i,j,m,res;
printf("Enter the size of the array: ");
scanf("%d",&n);
printf("Enter the elements: ");
for(i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
printf("Enter the element to be searched: ");
scanf("%d",&se);
i=0;
Roll No 2 2 A 9 5 A 6 1 0 6
2
j=n-1;
int f=0;
while(i<=j)
{
m=(i+j)/2;
if(arr[m]==se)
{
f=1;
printf("Element found at index %d ",m);
break;
}
else if(arr[m]>se)
{
j=m-1;
}
else
{
i=m+1;
}
}
if(f==0)
{
printf("Element not found");
}
Output
Roll No 2 2 A 9 5 A 6 1 0 6
3
Experiment 2 Date:
Aim: Develop a program and measure the running time for Merge Sort with Divide and Conquer
Description
Merge sort is the sorting technique that follows the divide and conquer approach. It works by dividing
an array into smaller subarrays, sorting each subarray, and then merging the sorted subarrays back
together to form the final sorted array.
It is a recursive algorithm that continuously splits the array in half until it cannot be further divided
i.e., the array has only one element left (an array with one element is always sorted). Then the sorted
subarrays are merged into one sorted array
Code
#include<stdio.h>
void merge(int *arr,int si,int m,int ei)
{
int i=si;
int j=m+1;
int k=0;
int temp[ei-si+1];
while(i<=m && j<=ei)
{
if(arr[i]<=arr[j])
{
temp[k++]=arr[i++];
}
else
{
temp[k++]=arr[j++];
}
}
while(i<=m)
{
Roll No 2 2 A 9 5 A 6 1 0 6
4
temp[k++]=arr[i++];
}
while(j<=ei)
{
temp[k++]=arr[j++];
}
int s=0;
for(i=si;i<=ei;i++)
{
arr[i]=temp[s++];
}
}
void divide(int *arr,int beg,int end)
{
if(beg<end)
{
int mid=(beg+end)/2;
divide(arr, beg,mid);
divide(arr,mid+1,end);
merge(arr,beg,mid,end);
}
}
void main()
{
int n,i,beg,end;
printf("Enter the size of the array: ");
scanf("%d",&n);
printf("Enter the elements in the array: ");
int arr[n];
for(i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
printf("array before mergesort \n");
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
Roll No 2 2 A 9 5 A 6 1 0 6
5
beg=0;
end=n-1;
divide(arr,beg,end);
printf("\n");
printf("array after mergesort \n");
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
}
Output
Roll No 2 2 A 9 5 A 6 1 0 6
6
EXPERIMENT-3
AIM: Develop a program and measure the running time for Quick Sort with Divide and Conquer
Description:
Quick Sort is a sorting algorithm based on the Divide and Conquer algorithm that picks an
element as a pivot and partitions the given array around the picked pivot by placing the pivot in
its correct position in the sorted array.
The key process in quick Sort is a partition(). The target of partitions is to place the pivot (any
element can be chosen to be a pivot) at its correct position in the sorted array and put all smaller
elements to the left of the pivot, and all greater elements to the right of the pivot.Partition is
done recursively on each side of the pivot after the pivot is placed in its correct position and this
finally sorts the array.
Code:
int j;
Roll No 2 2 A 9 5 A 6 1 0 6
7
Output:
Roll No 2 2 A 9 5 A 6 1 0 6
8
Experiment 4 Date:
Aim: Develop a program and measure the running time for estimating minimum-cost
spanning Trees with Greedy Method
Description:
Spanning tree - A spanning tree is the subgraph of an undirected connected graph.
Minimum Spanning tree - Minimum spanning tree can be defined as the spanning tree in
which the sum of the weights of the edge is minimum. The weight of the spanning tree is the
sum of the weights given to the edges of the spanning tree.
Prim’s Algorithm :
Prim’s Algorithm is an approach to determine minimum cost spanning tree. In this case, we
start with single edge of graph and we add edges to it and finally we get minimum cost tree.
In this case, as well, we have n-1 edges when number of nodes in graph are n. We again and
again add edges to tree and tree is extended to create spanning tree, while in case of Kruskal’s
algorithm there may be more than one tree, which is finally connected through edge to create
spanning tree.
Program:
// Prim’s Algorithm
#include <stdio.h>
#include <stdlib.h>
#define INFINITY 9999
#define MAX 20
int G[MAX][MAX], spanning[MAX][MAX], n;
int prims();
int main() {
int i, j, total_cost;
printf("Enter no. 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]);
}
}
total_cost = prims();
Roll No 2 2 A 9 5 A 6 1 0 6
9
Roll No 2 2 A 9 5 A 6 1 0 6
10
no_of_edges = n - 1;
while(no_of_edges > 0) {
min_distance = INFINITY;
for(i = 1; i < n; i++) {
if(visited[i] == 0 && distance[i] < min_distance) {
v = i;
min_distance = distance[i];
}
}
u = from[v];
spanning[u][v] = distance[v];
spanning[v][u] = distance[v];
no_of_edges--;
visited[v] = 1;
for(i = 1; i < n; i++) {
if(visited[i] == 0 && cost[i][v] < distance[i]) {
distance[i] = cost[i][v];
from[i] = v;
}
}
min_cost += cost[u][v];
}
return min_cost;
}
Roll No 2 2 A 9 5 A 6 1 0 6
11
Output:
Roll No 2 2 A 9 5 A 6 1 0 6
12
Kruskal's Algorithm :
Kruskal's Algorithm is used to find the minimum spanning tree for a connected weighted
graph. The main target of the algorithm is to find the subset of edges by using which we can
traverse every vertex of the graph. It follows the greedy approach that finds an optimum
solution at every stage instead of focusing on a global optimum.
The time complexity of Kruskal's algorithm is O(E logE) or O(V logV), where E is the no. of
edges, and V is the no. of vertices
Program:
// Kruskal's Algorithm
#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);
Roll No 2 2 A 9 5 A 6 1 0 6
13
Roll No 2 2 A 9 5 A 6 1 0 6
14
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)
{
Roll No 2 2 A 9 5 A 6 1 0 6
15
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\n", cost);
}
Output :
Roll No 2 2 A 9 5 A 6 1 0 6
16
Experiment 5 Date:
Aim: Develop a program and measure the running time for estimating Single Source Shortest
Paths with Greedy Method.
Description:
Vertices: Vertices are the basic units of the graph used to represent real-life objects, persons,
or entities. Sometimes, vertices are also known as Nodes.
Edges: Edges are drawn or used to connect two vertices of the graph. Sometimes, edges are
also known as Arcs.
Dijkstra's Algorithm is a Graph algorithm that finds the shortest path from a source vertex to
all other vertices in the Graph (single source shortest path). It is a type of Greedy Algorithm
that only works on Weighted Graphs having positive weights. The time complexity of
Dijkstra's Algorithm is O(V2) with the help of the adjacency matrix representation of the
graph. This time complexity can be reduced to O((V + E) log V) with the help of an
adjacency list representation of the graph, where V is the number of vertices and E is the
number of edges in the graph.
Program:
#include <stdio.h>
#define INFINITY 9999
#define MAX 10
void dijkstra(int G[MAX][MAX], int n, int startnode);
int main() {
int G[MAX][MAX], i, j, n, u;
printf("Enter no. 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]);
}
}
printf("\nEnter the starting node: ");
scanf("%d", &u);
dijkstra(G, n, u);
return 0;
Roll No 2 2 A 9 5 A 6 1 0 6
17
}
void dijkstra(int G[MAX][MAX], int n, int startnode) {
int cost[MAX][MAX], distance[MAX], pred[MAX];
int visited[MAX], count, mindistance, nextnode, i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (G[i][j] == 0) {
cost[i][j] = INFINITY;
} else {
cost[i][j] = G[i][j];
}
}
}
for (i = 0; i < n; i++) {
distance[i] = cost[startnode][i];
pred[i] = startnode;
visited[i] = 0;
}
distance[startnode] = 0;
visited[startnode] = 1;
count = 1;
while (count < n - 1) {
mindistance = INFINITY;
for (i = 0; i < n; i++) {
if (distance[i] < mindistance && !visited[i]) {
mindistance = distance[i];
nextnode = i;
}
}
visited[nextnode] = 1;
for (i = 0; i < n; i++) {
Roll No 2 2 A 9 5 A 6 1 0 6
18
if (!visited[i]) {
if (mindistance + cost[nextnode][i] < distance[i]) {
distance[i] = mindistance + cost[nextnode][i];
pred[i] = nextnode;
}
}
}
count++;
}
for (i = 0; i < n; i++) {
if (i != startnode) {
printf("\nDistance of node%d=%d ", i, distance[i]);
printf("\nPath=%d ", i);
j = i;
do {
j = pred[j];
printf("<-%d", j);
} while (j != startnode);
}
}
}
Output:
Roll No 2 2 A 9 5 A 6 1 0 6
19
Experiment 6 Date:
Aim: Develop a program and measure the running time for optimal Binary search trees with
Dynamic Programming.
Description:
An Optimal Binary Search Tree (OBST), also known as a Weighted Binary Search Tree, is
a binary search tree that minimizes the expected search cost. In a binary search tree, the
search cost is the number of comparisons required to search for a given key.
In an OBST, each node is assigned a weight that represents the probability of the key being
searched for. The sum of all the weights in the tree is 1.0. The expected search cost of a
node is the sum of the product of its depth and weight, and the expected search cost of its
children.
Program:
#include <stdio.h>
#include <limits.h>
int sum(int freq[], int i, int j);
int optCost(int freq[], int i, int j)
{
if (j < i)
return 0;
if (j == i)
return freq[i];
int fsum = sum(freq, i, j);
int min = INT_MAX;
int r;
for (r = i; r <= j; ++r)
{
Roll No 2 2 A 9 5 A 6 1 0 6
20
Output:
Roll No 2 2 A 9 5 A 6 1 0 6
21
Roll No 2 2 A 9 5 A 6 1 0 6