0% found this document useful (0 votes)
120 views33 pages

DSA Graphs: DFS, BFS, and MST Algorithms

The document covers key concepts in graph theory and algorithms, including graph definitions, types (directed, undirected, weighted, unweighted), and operations such as Depth-First Search (DFS) and Breadth-First Search (BFS). It also explains Minimum Cost Spanning Trees using Kruskal's and Prim's algorithms, including their steps and implementations in C programming. Additionally, it provides example codes for BFS, DFS, and both spanning tree algorithms.

Uploaded by

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

DSA Graphs: DFS, BFS, and MST Algorithms

The document covers key concepts in graph theory and algorithms, including graph definitions, types (directed, undirected, weighted, unweighted), and operations such as Depth-First Search (DFS) and Breadth-First Search (BFS). It also explains Minimum Cost Spanning Trees using Kruskal's and Prim's algorithms, including their steps and implementations in C programming. Additionally, it provides example codes for BFS, DFS, and both spanning tree algorithms.

Uploaded by

Darth Vader
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

UNIT 5

Graphs: Graph Abstract Data Type, Elementary Graph operations (DFS and BFS), Minimum
Cost Spanning Trees (Prim ‘s and Kruskal ‘s Algorithms).
Sorting and Searching: Insertion sort, Quick sort, Best computing time for Sorting, Merge
sort, Heap sort, Shell sort, Sorting on Several Keys, List and Table Sorts, Summary of Internal
Sorting, Linear and Binary Search algorithms
==========================================================================

Graph Definition
Graph consists of a finite set of vertices and set of Edges or Links which connect to a pair of
nodes.
A Graph is a non-linear data structure of nodes and edges.
Trees Graphs
1 Only one path | edge between two Multiple paths | edges | links among two
nodes. nodes.
2 Has a root node No root node
3 Don’t have loops Can have loops
4 If graph has N nodes, N-1 edges No of edges not defined
5 Hierarchical Model Network Model

Graph
Tree

16 16

54 19
54 19

67 32
67 87
87
A tree is an undirected graph.

DSA UNIT 5 MRS. MADHAVI


Directed Graph (Digraph)
A directed graph is a set of vertices or nodes connected by edges with each node having a
direction associated with it.
Edges are usually represented by arrows pointing in the direction the graph can be traversed.

Undirected Graph
In an undirected graph the edges are bidirectional with no direction associated with them.
Hence, the graph can be traversed in either direction. The absence of an arrow tells us that
the graph is undirected.

Directed Graphs Undirected Graph

16 16

54 19 54 19

32 32
67
67
87 87

Unweighted Graph
 An unweighted graph is a graph in which all edges | paths are considered to have
same weight.

Weighted Graph
 A weighted graph is graph in which each branch is given a numerical weight.

DSA UNIT 5 MRS. MADHAVI


Graph Operations
Depth-first search (DFS)
DFS is an algorithm for traversing or searching tree or graph data structures. The algorithm
starts at the root node selecting some node as the root node in the case of a graph and
explores as far as possible along each branch before backtracking. It uses last in- first-out
strategy and hence it is implemented using a stack.
Question. Which solution would DFS find to move from node S to node G if run on the graph below?

H Adjacency List
A: B,D
B: C,F
C: E,G,H
A B C G D: F
E: F,B
F: A
D F E G: E,H
H: A

Solution. The equivalent search tree for the above graph is as follows. As DFS traverses the
tree “deepest node first”, it would always pick the deeper branch until it reaches the solution
or it runs out of nodes and goes to the next branch. The traversal is shown in blue arrows.

Path: A→B→C→E→F→D→G→H
= the depth of the search tree = the number of levels of the search tree.
= number of nodes in level .
Time complexity: Equivalent to the number of nodes traversed in DFS

Space complexity: Equivalent to how large can the fringe get.

Completeness: DFS is complete if the search tree is finite, meaning for a given finite search
tree, DFS will come up with a solution if it exists.

Optimality: DFS is not optimal, meaning the number of steps in reaching the solution, or the
cost spent in reaching it is high.

DSA UNIT 5 MRS. MADHAVI


Breadth-first search
BFS is an algorithm for traversing or searching tree or graph data structures. It starts at
the tree root or some node of a graph, sometimes referred to as a ‘search key’ and explores
all of the neighbour nodes at the present depth prior to moving on to the nodes at the next
depth level. It is implemented using a queue.
Example:
Question. Which solution would BFS find to move from node S to node G if run on the graph
below?

Adjacency List
A B C G A: B,D
B: C,F
C: E,G,H
D F E D: F
E: F,B
F: A
G: E,H

Breadth-First Search (BFS) is a graph traversal algorithm that explores all the vertices of
a graph layer by layer. It starts from a source vertex and explores all its neighbors before
moving to the next level of neighbors.
Algorithm
1. Initialize:
 Create a queue and enqueue the starting vertex.
 Mark the starting vertex as visited.
2. Process the Queue:
 Dequeue a vertex from the queue.
 For each unvisited adjacent vertex of the dequeued vertex:
 Mark it as visited.
 Enqueue it.

3. Repeat step 2 until the queue is empty.

BFS Order: A → B → D→ C → F → E → G

Time complexity: Equivalent to the number of nodes traversed in BFS until the shallowest
solution.

DSA UNIT 5 MRS. MADHAVI


Space complexity: Equivalent to how large can the fringe get.

Completeness: BFS is complete, meaning for a given search tree, BFS will come up with a
solution if it exists.

Optimality: BFS is optimal as long as the costs of all edges are equal.

A C Program that makes traversal methods for BFS and DFS from a given source
vertex.
#include <stdio.h>
#include <stdlib.h>

#define MAX 100

int graph[MAX][MAX], visited[MAX], queue[MAX], front = -1, rear = -1;

void bfs(int start, int n)


{
int i;
printf("%d ", start);
visited[start] = 1;
queue[++rear] = start;
while (front != rear)
{
start = queue[++front];
for (i = 1; i <= n; i++)
{
if (graph[start][i] == 1 && !visited[i])
{
queue[++rear] = i;
visited[i] = 1;
printf("%d ", i);
}
}
}
}

void dfs(int start, int n)


{
int i;
printf("%d ", start);
visited[start] = 1;
for (i = 1; i <= n; i++)
DSA UNIT 5 MRS. MADHAVI
{
if (graph[start][i] == 1 && !visited[i])
{
dfs(i, n);
}
}
}

int main()
{
int n, i, j, start;
printf("Enter the number of vertices: ");
scanf("%d", &n);
printf("Enter the adjacency matrix:\n");
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
scanf("%d", &graph[i][j]);
}
}
printf("Enter the starting vertex: ");
scanf("%d", &start);
printf("BFS Traversal: ");
for (i = 1; i <= n; i++)
{
visited[i] = 0;
}
bfs(start, n);
printf("\nDFS Traversal: ");
for (i = 1; i <= n; i++)
{
visited[i] = 0;
}
dfs(start, n);
return 0;
}
/*INPUT
Enter the number of vertices and edges: 6 7
Enter edge (u v): 1 2
Enter edge (u v): 1 3
Enter edge (u v): 1 4km,
Enter edge (u v): 2 5
Enter edge (u v): 4 6
Enter edge (u v): 5 6
DSA UNIT 5 MRS. MADHAVI
Enter edge (u v): 3 4
Enter the starting vertex: 1
Enter the starting vertex: 1
OUTPUT
BFS Traversal: 1 2 3 4 5 6
DFS Traversal: 1 2 5 3 4 6

Minimum Cost Spanning Tree - using Kruskal’s algorithm


Kruskal's algorithm to find the minimum cost spanning tree uses the greedy approach. This
algorithm treats the graph as a forest and every node it has as an individual tree. A tree
connects to another only and only if, it has the least cost among all available options and
does not violate MST properties.

Step 1 Sort All Edges:


 Sort all edges in the graph in ascending order of their weights.
Step 2 Initialize Data Structures:
 Use a union-find (disjoint-set) data structure to keep track of connected components.
Steo 3 Process Edges:
 Start with an empty MST.
 Iterate through the sorted edges, and for each edge:
o Check if the edge connects two different components (using the union-find data
structure).
o If it does, add the edge to the MST and merge the components.
Step 5 Output:
 The MST, which includes all vertices and the minimum total weight.

5
A E
1 10
7 2

B C D
3 4

DSA UNIT 5 MRS. MADHAVI


Step 1 - First, add the edge AB with weight 1 to the MST.

Step 2 - Add the edge DE with weight 2 to the MST as it is not creating the cycle.

Step 3 - Add the edge BC with weight 3 to the MST, as it is not creating any cycle or loop.

Step 4 - Now, pick the edge CD with weight 4 to the MST, as it is not forming the cycle.

Step 5 - After that, pick the edge AE with weight 5. Including this edge will create the
cycle, so discard it.
Step 6 - Pick the edge AC with weight 7. Including this edge will create the cycle, so discard
it.

DSA UNIT 5 MRS. MADHAVI


Step 7 - Pick the edge AD with weight 10. Including this edge will also create the cycle, so
discard it.
So, the final minimum spanning tree obtained from the given weighted graph by using
Kruskal's algorithm

The cost of the MST is = AB + DE + BC + CD = 1 + 2 + 3 + 4 = 10.


Now, the number of edges in the above tree equals the number of vertices minus 1. So, the
algorithm stops here.
Write a C program that implements kruskal algorithm that reads elements from
keyboard

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

struct Edge
{
int src, dest, weight;
};

struct Graph
{
int V, E;
struct Edge edges[MAX];
};

int find(int parent[], int i)


{
while (parent[i] != i)
i = parent[i];
return i;
}

void unionSet(int parent[], int rank[], int x, int y)


{
int rootX = find(parent, x);
DSA UNIT 5 MRS. MADHAVI
int rootY = find(parent, y);
if (rank[rootX] < rank[rootY])
parent[rootX] = rootY;
else if (rank[rootX] > rank[rootY])
parent[rootY] = rootX;
else {
parent[rootY] = rootX;
rank[rootX]++;
}
}

void kruskalMST(struct Graph *graph)


{
int V = graph->V;
struct Edge result[MAX];
int i,j, parent[V], rank[V];
for (i = 0; i < V; i++)
{
parent[i] = i;
rank[i] = 0;
}
for (i = 0; i < graph->E; i++)
{
for (j = i + 1; j < graph->E; j++)
{
if (graph->edges[i].weight > graph->edges[j].weight)
{
struct Edge temp = graph->edges[i];
graph->edges[i] = graph->edges[j];
graph->edges[j] = temp;
}
}
}
int e = 0;
for (i = 0; e < V - 1 && i < graph->E; i++)
{
struct Edge nextEdge = graph->edges[i];
int x = find(parent, [Link]);
int y = find(parent, [Link]);
if (x != y)
{
result[e++] = nextEdge;
unionSet(parent, rank, x, y);
}
}
DSA UNIT 5 MRS. MADHAVI
printf("Edge \tWeight\n");
for (i = 0; i < e; i++)
printf("%d - %d \t%d\n", result[i].src, result[i].dest, result[i].weight);
}

int main()
{
struct Graph graph;
int i;
printf("Enter the number of vertices: ");
scanf("%d", &graph.V);
printf("Enter the number of edges: ");
scanf("%d", &graph.E);
printf("Enter the edges in the format (src dest weight):\n");
for (i = 0; i < graph.E; i++)
scanf("%d %d %d", &[Link][i].src, &[Link][i].dest, &[Link][i].weight);
kruskalMST(&graph);
return 0;
}
/* Input
Enter the number of vertices: 4
Enter the number of edges: 5
Enter the edges in the format (src dest weight):
0 1 10
026
035
1 3 15
234

Minimum Cost Spanning Tree - using Prims Algorithm


Prim's algorithm to find minimum cost spanning tree (as Kruskal's algorithm) uses the
greedy approach.
Prim's algorithm shares a similarity with the shortest path first algorithms.
 Prim’s Algorithm is a famous greedy algorithm.
 It is used for finding the Minimum Spanning Tree (MST) of a given graph.
 To apply Prim’s algorithm, the given graph must be weighted, connected and
undirected
Steps of Prim's Algorithm
1. Initialize:
 Start with an arbitrary node as the initial vertex.
 Maintain a set of vertices already included in the MST.
DSA UNIT 5 MRS. MADHAVI
 Use a priority queue (or an array) to store the edges connected to the MST,
sorted by weight.
2. Process:
 Select the edge with the smallest weight that connects a vertex in the MST to a
vertex outside it.
 Add the selected edge and its vertex to the MST.
3. Repeat:

 Continue adding the smallest edge until all vertices are included in the MST.
4. Output:

 The MST, which includes all vertices and the minimum total weight.

Example: Construct the minimum spanning tree (MST) for the given graph using Prim’s
Algorithm-

The above discussed steps are followed to find the minimum cost spanning tree using
Prim’s Algorithm-
STEP 1

Step 2

DSA UNIT 5 MRS. MADHAVI


Step 3

Step 4

Step 5

Step 6

Since all the vertices have been included in the MST, so we stop.

Now, Cost of Minimum Spanning Tree


= Sum of all edge weights
= 10 + 25 + 22 + 12 + 16 + 14
DSA UNIT 5 MRS. MADHAVI
= 99 units
Write a C program that implements prim's algorithm

#include <stdio.h>
#include <limits.h>

#define V 5

int minKey(int key[], int mstSet[])


{
int min = INT_MAX, min_index = -1;
int v;
for (v = 0; v < V; v++)
{
if (mstSet[v] == 0 && key[v] < min)
{
min = key[v], min_index = v;
}
}
return min_index;
}

void printMST(int parent[], int graph[V][V])


{
printf("Edge \tWeight\n");
int i;
for (i = 1; i < V; i++)
{
printf("%d - %d \t%d\n", parent[i], i, graph[i][parent[i]]);
}
}

void primMST(int graph[V][V])


{
int parent[V], key[V], mstSet[V];
int i;
for (i = 0; i < V; i++)
{
key[i] = INT_MAX, mstSet[i] = 0;
}
key[0] = 0;
parent[0] = -1;
int count;
for (count = 0; count < V - 1; count++)
DSA UNIT 5 MRS. MADHAVI
{
int u = minKey(key, mstSet);
mstSet[u] = 1;
int v;
for (v = 0; v < V; v++)
{
if (graph[u][v] && mstSet[v] == 0 && graph[u][v] < key[v])
{
parent[v] = u, key[v] = graph[u][v];
}
}
}
printMST(parent, graph);
}

int main()
{
int i,j,graph[V][V];
printf("Enter the adjacency matrix of the graph (%d x %d):\n", V, V);
for (i = 0; i < V; i++)
{
for (j = 0; j < V; j++)
{
scanf("%d", &graph[i][j]);
}
}
primMST(graph);
return 0;
}
/*Input
02060
20385
03007
68009
05790

Output
Edge Weight
0-1 2
1-2 3
0-3 6
1-4 5

DSA UNIT 5 MRS. MADHAVI


Insertion Sort
Insertion Sort is a simple sorting algorithm that builds the final sorted array one item at a
time. It is like sorting playing cards in your hands. Take one card at a time and insert it
into its correct position relative to the cards already sorted.
Algorithm Steps:
1. Divide the Array:
 Treat the first element as already sorted.
 The rest of the array is unsorted.
2. Iterate Over the Array:
 Pick the next element from the unsorted portion.
 Compare it with the elements in the sorted portion.
 Insert it into its correct position in the sorted portion.
3. Repeat:

 Continue until all elements are sorted.


Example
Given Array: 7,2,4,10,3
1. Initial Array:
7,2,4,10,3

 First element 7 is considered sorted.


2. Insert 2:
Compare 2 with 7. 2 is smaller, so insert it before 7.
2,7,4,10,3
3. Insert 4:
Compare 4 with 7 and 2. 4 is smaller than 7 but larger than 2. Insert it between 2
and 7.
2,4,7,10,3
4. Insert 10:
Compare 10 with 7. 10 is larger, so it stays in its place.
2,4,7,10,3
5. Insert 3:
Compare 3 with 10, 7, 4, and 2. 3 is larger than 2 but smaller than 4. Insert it
between 2 and 4.
2,3,4,7,10

DSA UNIT 5 MRS. MADHAVI


Write a C Program that implements Insertion sort

#include <stdio.h>

void insertionSort(int arr[], int n)


{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;

while (j >= 0 && arr[j] > key)


{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}

void printArray(int arr[], int n)


{
int i;
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}

int main()
{
int n, i;

printf("Enter the number of elements: ");


scanf("%d", &n);

int arr[n];
printf("Enter %d elements:", n);
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
DSA UNIT 5 MRS. MADHAVI
insertionSort(arr, n);

printf("Sorted array: ");


printArray(arr, n);

return 0;
}
Input
Enter the number of elements: 7
Enter 7 elements:88 11 99 22 55 33 44

OUTPUT
Sorted array: 11 22 33 44 55 88 99

QUICK Sort
Algorithm
1. Choose a Pivot
 Select an element as the pivot (commonly the last element, the first element, or
a random element).
2. Partition the Arra
 Rearrange the array so that:
 Elements smaller than the pivot are on the left.
 Elements larger than the pivot are on the right.
o The pivot is now in its correct position.
3. Recursively Sort:
o Apply the same steps to the subarrays on the left and right of the pivot.

Example Given Array: 8,3,1,7,0,10,2


1. Choose Pivot:
Pivot = 2 (last element).

2. Partition:
Rearrange the array so elements smaller than 2 are to the left, and larger elements
are to the right.
0,1,2,8,7,10,3
Pivot 2 is now in its correct position.

3. Recursively Sort:
o Left Subarray: 0,1
o Right Subarray: 8,7,10,3

4. Sort Left Subarray [0,1]


o Pivot = 1.
DSA UNIT 5 MRS. MADHAVI
o Partition: 0,1.

5. Sort Right Subarray [8,7,10,3]


o Pivot = 3.
o Partition: 3,7,8,10.

6. Combine:
o Final sorted array: 0,1,2,3,7,8,10

Write a C Program that implements Quick Sort

#include <stdio.h>

int partition(int arr[], int low, int high)


{
int j;
int pivot = arr[high], i = low - 1;
for (j = low; j < high; j++)
{
if (arr[j] < pivot)
{
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}

void quickSort(int arr[], int low, int high)


{
if (low < high)
{
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

DSA UNIT 5 MRS. MADHAVI


int main()
{
int i, n;
printf("Enter number of elements: ");
scanf("%d", &n);
int arr[n];
printf("Enter the elements: ");
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
quickSort(arr, 0, n - 1);
printf("Sorted elements: ");
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

Input
Enter number of elements: 6
Enter the elements: 88 66 44 11 55 22

OUTPUT
Sorted elements: 11 22 44 55 66 88

Best Computing time for Sorting


The best computing time for sorting depends on the algorithm used, the characteristics of
the input data and whether additional constraints (e.g., stability, in-place sorting) are
imposed. Below is an explanation of the best-case scenarios for common sorting algorithms
and theoretical lower bounds for sorting.

Best Time Complexity: O(nlogn)


 For comparison-based sorting algorithms (e.g., Quick Sort, Merge Sort, Heap Sort), the
best possible time complexity is O(nlogn).
 This is because comparison-based sorting involves a decision tree with n!n!n!
permutations, and the height of the tree is approximately log⁡2(n!)\log_2(n!)log2(n!),
which is O(nlogn).

Sorting Algorithm Best-Case


1. Bubble Sort
 Best Case Time Complexity: O(n)
 Occurs when the array is already sorted.
DSA UNIT 5 MRS. MADHAVI
 In this case, no swaps are needed, and only one pass through the array is required to
confirm that it is sorted.

2. Insertion Sort
 Best Case Time Complexity: O(n)
 Occurs when the array is already sorted.
 The algorithm iterates through the array but does not perform any shifts or swaps

[Link] Sort
 Best Case Time Complexity: O(n2)
 Selection Sort always requires n−1 comparisons for the first element, n−2 for the
second, and so on, regardless of the input's order.

4. Merge Sort
 Best Case Time Complexity: O(nlogn)
 Merge Sort always divides the array into halves and merges them in O(n), so its best,
worst, and average case time complexities are O(nlogn).

5. Quick Sort
 Best Case Time Complexity: O(nlogn)
 Occurs when the pivot divides the array into two equal halves at each step.
 Requires fewer recursive calls and fewer comparisons.

6. Heap Sort
 Best Case Time Complexity: O(nlogn)
 Heap Sort always builds a heap and extracts elements, so its time complexity does not
depend on input order.
7. Counting Sort, Radix Sort, Bucket Sort
 These are non-comparison-based algorithms and can achieve:
o Best Case Time Complexity: O(n)
o Applicable only when specific conditions (like integer keys or small ranges) are
met.
Algorithm Best Case Average Case Worst Case

Bubble Sort O(n) O(n2) O(n2)


Insertion Sort O(n) O(n2) O(n2)
Selection Sort O(n2) O(n2) O(n2)
Merge Sort O(n log n) O(n log n) O(n log n)
Quick Sort O(n log n) O(n log n) O(n log n)
Heap Sort O(n log n) O(n log n) O(n log n)
Counting Sort O(n) O(n) O(n)
Radix Sort O(n) O(n) O(n)

DSA UNIT 5 MRS. MADHAVI


MERGE Sort
 Merge Sort is a popular sorting algorithm that uses the divide-and-conquer strategy to
sort an array.
 It divides the array into smaller subarrays, sorts them, and then merges the sorted
subarrays back together to produce the final sorted array.
 It is a Stable algorithm
 It is outplace algorithm
 Time complexity is O(n log n) in every case.

Algorithm Steps
1. Divide:
 Divide the array into two halves.
2. Conquer:
 Recursively apply merge sort to the two halves until each subarray contains a
single element (base case).
3. Combine:
 Merge the two sorted halves into a single sorted array.

Example Given Array: 8,3,1,7,0,10,2


Step-by-Step Process:
1. Divide: Split the array into two halves: 8,3,1,7 and 0,10,2

2. Conquer (Recursive Sorting):


o Left Half: 8,3,1,7
 Divide: 8,3 and 1,7
 Sort 8,3 Merge into 3,8
 Sort 1,7: Merge into 1,7
 Merge 3,8 and 1,7 into 1,3,7,8

Right Half: 0,10,2


o
 Divide: 0,10 and 2
 Sort 0,10: Merge into 0, 10
 Merge 0, 10 and 2 into 0,2, 10
3. Combine:
o Merge 1,3,7,8 and 0,2, 10 into 0,1,2,3,7,8,10.

Write a C Program that implements Merge Sort


#include <stdio.h>

void merge(int arr[], int left, int mid, int right)


{
int n1, n2, i, j, k;
n1 = mid - left + 1;
DSA UNIT 5 MRS. MADHAVI
n2 = right - mid;
int L[n1], R[n2];

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


{
L[i] = arr[left + i];
}
for (i = 0; i < n2; i++)
{
R[i] = arr[mid + 1 + i];
}

i = 0; j = 0; k = left;

while (i < n1 && j < n2)


{
if (L[i] <= R[j])
{
arr[k] = L[i]; i++;
}
else
{
arr[k] = R[j]; j++;
}
k++;
}
while (i < n1)
{
arr[k] = L[i]; i++; k++;
}
while (j < n2)
{
arr[k] = R[j]; j++; k++;
}
}

void mergeSort(int arr[], int left, int right)


{
int mid;
if (left < right)
{
mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
DSA UNIT 5 MRS. MADHAVI
}
}

int main()
{
int n, i;
printf("Enter number of elements: ");
scanf("%d", &n);
int arr[n];
printf("Enter the elements: ");
for (i = 0; i < n; i++) { scanf("%d", &arr[i]); }
mergeSort(arr, 0, n - 1);
printf("Sorted elements: ");
for (i = 0; i < n; i++) { printf("%d ", arr[i]); }
return 0;
}

Input
Enter number of elements: 6
Enter the elements: 88 66 44 11 55 22

OUTPUT
Sorted elements: 11 22 44 55 66 88

HEAP Sort
 Heap Sort is a comparison-based sorting algorithm that uses the properties of a
binary heap data structure to sort elements.
 It is an in-place, unstable sorting algorithm that efficiently sorts an array by
repeatedly building a heap and extracting the largest or smallest element.

Binary Heap

 A binary heap is a complete binary tree where


 Max-Heap: The parent node is greater than or equal to its children.
 Min-Heap: The parent node is smaller than or equal to its children.

Heap Property:
 The largest or smallest element is always at the root of the heap.

Heapify Operation:
 Ensures that the heap property is maintained in a subtree.

Steps in Heap Sort


 Build a Max-Heap: Arrange the array to satisfy the max-heap property.
DSA UNIT 5 MRS. MADHAVI
 Extract Elements: Repeatedly extract the largest element (root of the heap), move it to
the end of the array, and reduce the heap size.
 Restore Heap Property: Apply the heapify operation to maintain the heap structure.

Algorithm Steps
1. Build a Max-Heap
 Convert the input array into a max-heap using the heapify operation.
2. Sort the Array
 Swap the root (largest element) with the last element.
 Reduce the heap size by 1.
 Apply heapify to restore the heap property.
 Repeat until the heap size is reduced to 1.

Example Given Array: 4,10,3,5,1


1. Build Max-Heap:
Convert the array into a max-heap: 10,5,3,4,1
2. Sort the Array:
 Swap 10 (root) with 1 (last element): 1,5,3,4,10
 Reduce heap size and heapify: 5,4,3,1,10
 Swap 5 (root) with 1 (last element): 1,4,3,5,10
 Reduce heap size and heapify: 4,1,3,5,10
 Repeat until sorted: 1,3,4,5,10

Write a C Program that implements heap sort


#include <stdio.h>

void heapify(int arr[], int n, int i)


{
int largest = i, left = 2 * i + 1, right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
{
largest = left;
}
if (right < n && arr[right] > arr[largest])
{
largest = right;
}
if (largest != i)
{
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, n, largest);
DSA UNIT 5 MRS. MADHAVI
}
}

void heapSort(int arr[], int n)


{
int i;
for (i = n / 2 - 1; i >= 0; i--)
{
heapify(arr, n, i);
}
for (i = n - 1; i > 0; i--)
{
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}

int main()
{
int i, n, arr[n];
printf("Enter number of elements: ");
scanf("%d", &n);

printf("Enter the elements: ");


for (i = 0; i < n; i++)
scanf("%d", &arr[i]);

heapSort(arr, n);
printf("Sorted elements: ");
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
INPUT
Enter number of elements: 8
Enter the elements: 22 99 77 66 11 55 33 44

OUTPUT
Sorted elements: 11 22 33 44 55 66 77 99

DSA UNIT 5 MRS. MADHAVI


Shell Sort
 Shell Sort is an in-place comparison-based sorting algorithm that improves upon
Insertion Sort by comparing and swapping elements that are far apart.
 It reduces the total number of swaps by allowing elements to move closer to their
correct positions early in the sorting process.

Algorithm
1. Initialize Gap
 Start with a gap size larger than 1 (e.g., half the array size).
2. Sort with Gap
 Perform a gapped version of insertion sort for the current gap size.
3. Reduce Gap
 Divide the gap size (commonly by 2 or other predefined methods).
4. Repeat
 Continue until the gap size is 1, at which point the array is sorted.

Example Given Array: 12,34,54,2,3

1. Initial Gap:
 Gap = ⌊n/2⌋=2.
Sort elements separated by a gap of 2:
 Compare 12 and 54 (no swap needed).
 Compare 3 and 2: Swap.
12,2,54,34,3
 Compare 54 and 3: Swap.
12,2,3,34,54
2. Reduce Gap:
 Gap = ⌊2/2⌋=1.
Perform a regular insertion sort:
 Compare adjacent elements and sort: 2,3,12,34,54
3. Final Sorted Array: 2,3,12,34,54

Write a C Program that implements Shell sort


#include <stdio.h>

void shellSort(int arr[], int n)


{
for (int gap = n / 2; gap > 0; gap /= 2)
for (int i = gap; i < n; i++)
{
int temp = arr[i], j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)

DSA UNIT 5 MRS. MADHAVI


arr[j] = arr[j - gap];
arr[j] = temp;
}
}

int main()
{
int i, n;
printf("Enter number of elements: ");
scanf("%d", &n);

int arr[n];
printf("Enter the elements: ");
for (i = 0; i < n; i++)
scanf("%d", &arr[i]);

shellSort(arr, n);
printf("Sorted elements: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);

return 0;
}

INPUT
Enter number of elements: 3
Enter the elements: 11 55 22

OUTPUT
Sorted elements: 11 22 55

Linear Search
Linear Search is a simple and straightforward algorithm used to search for an element in a
list or array.
It works by sequentially checking each element in the array until the target element is
found or the entire array is traversed.

How Linear Search Works


1. Start at the first element of the array.
2. Compare the current element with the target value.
3. If the current element matches the target, the search is successful, and the index is
returned.

DSA UNIT 5 MRS. MADHAVI


4. If the target is not found by the end of the array, the search returns a failure
indication (e.g., -1).

Algorithm
For an array arr of size n and a target element x:
1. Start a loop from index i = 0 to i < n.
2. Check if arr[i] == x.
3. If true, return i.
4. If the loop ends without finding the element, return -1.

Example Input

Array: 5,8,3,6,1
search: 6

Process:
1. Compare 5 with 6 → Not a match.
2. Compare 8 with 6 → Not a match.
3. Compare 3 with 6 → Not a match.
4. Compare 6 with 6 → Match found.

Output: Index of target: 3 (0-based index)

Advantages of Linear Search


1. Simplicity: Easy to understand and implement.
2. No Precondition: Works on both sorted and unsorted data.
3. Flexibility: Can be used on arrays, linked lists, or any data structure that can be
traversed sequentially.

Disadvantages of Linear Search


1. Inefficiency:
 Time complexity is O(n) in the worst case, which is slow for large
datasets.
2. Not Optimal: For sorted data, algorithms like Binary Search are much faster.

DSA UNIT 5 MRS. MADHAVI


Write a C Program that implements Linear Search
#include <stdio.h>

int linearSearch(int arr[], int n, int target)


{
int i;
for (i = 0; i < n; i++)
if (arr[i] == target)
return i;
return -1;
}

int main()
{
int arr[] = {5, 8, 3, 6, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 6;

int result = linearSearch(arr, n, target);


if (result != -1)
printf("Element found at index %d\n", result);
else
printf("Element not found\n");

return 0;
}

OUTPUT
Element found at index 3

Binary Search
Binary Search is an efficient algorithm used to find the position of a target element in a sorted
array. Unlike Linear Search, which checks each element one by one, Binary Search divides
the search space in half at each step, making it significantly faster.

How Binary Search Works


1. Precondition: The array must be sorted.
2. Initial Setup: Define two pointers, low and high, representing the range of the search.
Initially, low = 0 and high = n - 1.
3. Middle Point: Calculate the middle index as:

Mid = low+ (high-low)/2;


4. Comparison
DSA UNIT 5 MRS. MADHAVI
If the target is equal to the middle element, the search is successful.

If the target is less than the middle element, narrow the search to the left half

(high = mid − 1).
 If the target is greater than the middle element, narrow the search to the right
half (low = mid + 1).
5. Repeat: Continue this process until the target is found or the range is empty
(low>high).

Algorithm
For a sorted array arr of size n and target x:
1. Initialize low = 0 and high = n - 1.
2. While low <= high:
 Compute mid = low + (high - low) / 2.
 If arr[mid] == x, return mid.
 If arr[mid] > x, update high = mid - 1.
 If arr[mid] < x, update low = mid + 1.
3. If the loop exits, return -1 (target not found).

Advantages of Binary Search


1. Efficiency
o Significantly faster than linear search for large datasets.
o Time complexity is O(log n).
2. Simplicity
o Easy to implement for sorted arrays.
3. Versatility
o Can be used in both iterative and recursive approaches.

Disadvantages
1. Requires Sorting
o Only works on sorted data, so the array must be sorted beforehand.
2. Not Optimal for Small Arrays
o For small datasets, the overhead of calculating the middle index may not be
worth it.

DSA UNIT 5 MRS. MADHAVI


Write a C Program that reads elements in ascending order and
searches an element using BS
#include <stdio.h>

void binarySearch(int arr[], int size, int key)


{
int left = 0, right = size - 1;

while (left <= right)


{
int mid = left + (right - left) / 2;

if (arr[mid] == key)
{
printf("Element found at index %d\n", mid);
return;
}
else if (arr[mid] < key)
left = mid + 1;
else
right = mid - 1;
}

printf("Element not found\n");


}

int main()
{
int size, key;

printf("Enter the number of elements: ");


scanf("%d", &size);

int arr[size];

printf("Enter %d elements in sorted order: ", size);


int i;
for (i = 0; i < size; i++)
{
scanf("%d", &arr[i]);
}

DSA UNIT 5 MRS. MADHAVI


printf("Enter the element to search: ");
scanf("%d", &key);

binarySearch(arr, size, key);

return 0;
}

OUTPUT
Enter the number of elements: 9
Enter 9 elements in sorted order: 11 22 33 44 55 66 77 88 99
Enter the element to search: 77
Element found at index 6

ooo000ooo

DSA UNIT 5 MRS. MADHAVI

You might also like