0% found this document useful (0 votes)
53 views65 pages

DSA UNIT-5 Notes 2023

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

DSA UNIT-5 Notes 2023

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

Introduction to Graphs

Graph is a non linear data structure. It contains set of points known as nodes (or vertices) and

set of links known as edges (or Arcs). Here edges are used to connect the vertices. A graph is

defined as follows...
§

Graph is a collection of vertices and arcs in which vertices are connected with arcs

Graph is a collection of nodes and edges in which nodes are connected with edges
Generally, a graph G is represented as G = ( V , E ), where V is set of vertices and E is set of

edges.

Example

The following is a graph with 5 vertices and 6 edges.


This graph G can be defined as G = ( V , E )
Where V = {A,B,C,D,E} and E = {(A,B),(A,C)(A,D),(B,D),(C,D),(B,E),(E,D)}.
Graph Terminology
We use the following terms in graph data structure...

Vertex
Individual data element of a graph is called as Vertex. Vertex is also known as node. In
above example graph, A, B, C, D & E are known as vertices.

Edge
An edge is a connecting link between two vertices. Edge is also known as Arc. An edge
is represented as (startingVertex, endingVertex). For example, in above graph the link
between vertices A and B is represented as (A,B). In above example graph, there are 7
edges (i.e., (A,B), (A,C), (A,D), (B,D), (B,E), (C,D), (D,E)).

Edges are three types.

1. Undirected Edge - An undirected egde is a bidirectional edge. If there is undirected edge

between vertices A and B then edge (A , B) is equal to edge (B , A).

2. Directed Edge - A directed egde is a unidirectional edge. If there is directed edge

between vertices A and B then edge (A , B) is not equal to edge (B , A).

3. Weighted Edge - A weighted egde is a edge with value (cost) on it.

Undirected Graph
A graph with only undirected edges is said to be undirected graph.

Directed Graph
A graph with only directed edges is said to be directed graph.
Mixed Graph
A graph with both undirected and directed edges is said to be mixed graph.

End vertices or Endpoints


The two vertices joined by edge are called end vertices (or endpoints) of that edge.

Origin
If a edge is directed, its first endpoint is said to be the origin of it.

Destination
If a edge is directed, its first endpoint is said to be the origin of it and the other
endpoint is said to be the destination of that edge.

Adjacent
If there is a edge between vertices A and B then both A and B are said to be adjacent.
In other words, vertices A and B are said to be adjacent if there is a edge between them.

Incident
Edge is said to be incident on a vertex if the vertex is one of the endpoints of that edge.

Outgoing Edge
A directed edge is said to be outgoing edge on its origin vertex.

Incoming Edge
A directed edge is said to be incoming edge on its destination vertex.
Degree
Total number of edges connected to a vertex is said to be degree of that vertex.

Indegree
Total number of incoming edges connected to a vertex is said to be indegree of
that vertex.

Outdegree
Total number of outgoing edges connected to a vertex is said to be outdegree of
that vertex.

Parallel edges or Multiple edges


If there are two undirected edges with same end vertices and two directed edges
with same origin and destination, such edges are called parallel edges or multiple edges.

Self-loop
Edge (undirected or directed) is a self-loop if its two endpoints coincide with each other.

Simple Graph
A graph is said to be simple if there are no parallel and self-loop edges.

Path
A path is a sequence of alternate vertices and edges that starts at a vertex and ends
at other vertex such that each edge is incident to its predecessor and successor vertex.
Graph Representations
Graph data structure is represented using following representations...

1. Adjacency Matrix
2. Incidence Matrix
3. Adjacency List

Adjacency Matrix
In this representation, graph is represented using a matrix of size total number of
vertices by total number of vertices. That means graph with 4 vertices is represented
using a matrix of size 4X4. In this matrix, both rows and columns represents vertices.
This matrix is filled with either 1 or 0. Here, 1 represents that there is a edge from row
vertex to column vertex and 0 represents that there is no edge from row vertex to
column vertex.

For example, consider the following undirected graph representation...

Directed graph representation...


Incidence Matrix
In this representation, graph is represented using a matrix of size total number of vertices by
total number of edges. That means graph with 4 vertices and 6 edges is represented using a
matrix of size 4X6. In this matrix, rows represents vertices and columns represents edges. This
matrix is filled with 0 or 1 or -1. Here, 0 represents that the row edge is not connected to
column vertex, 1 represents that the row edge is connected as outgoing edge to column vertex
and -1 represents that the row edge is connected as incoming edge to column vertex.

For example, consider the following directed graph representation...

Adjacency List
In this representation, every vertex of a graph contains list of its adjacent vertices.

For example, consider the following directed graph representation implemented using
linked list...

This representation can also be implemented using array as follows..


Graph Traversal

Graph traversal is a technique used for searching vertex in a graph. The graph traversal is also
used to decide the order of vertices to be visited in the search process. A graph traversal finds
the edges to be used in the search process without creating loops. That means using graph
traversal we visit all the vertices of graph without getting into looping path.

There are two graph traversal techniques and they are as follows...

1. DFS (Depth First Search)


2. BFS (Breadth First Search)

BFS (Breadth First Search)


Spanning Tree
Spanning tree can be defined as a sub-graph of connected, undirected graph G that is a tree
produced by removing the desired number of edges from a graph. In other words, Spanning
tree is a non-cyclic sub-graph of a connected and undirected graph G that connects all the
vertices together. A graph G can have multiple spanning trees.

BFS traversal of a graph produces a spanning tree as final result. Spanning Tree is a graph
without loops. We use Queue data structure with maximum size of total number of vertices in
the graph to implement BFS traversal.

We use the following steps to implement BFS traversal...


 Step 1 - Define a Queue of size total number of vertices in the graph.
 Step 2 - Select any vertex as starting point for traversal. Visit that vertex and insert it
into the Queue.
 Step 3 - Visit all the non-visited adjacent vertices of the vertex which is at front of the
Queue and insert them into the Queue.
 Step 4 - When there is no new vertex to be visited from the vertex which is at front of
the Queue then delete that vertex.
 Step 5 - Repeat steps 3 and 4 until queue becomes empty.
 Step 6 - When queue becomes empty, then produce final spanning tree by
removing unused edges from the graph
Example 2

Queue

Status :

Output: A

Queue Status : B

S Output: A B S
Queue Status : C

G Output: A B S

Queue Status : G D E F

Output: A B S C
Queue Status : D E F H

Output: A B S C G

Queue Status : E F H

Output: A B S C G D
Queue Status : F H

Output: A B S C G D E

Queue Status : H

Output: A B S C G D E F
Queue Status :

Output: A B S C G D E F H

http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/11-Graph/bfs.html
Solution:
Minimum Path P can be found by applying breadth first search algorithm that will begin at node A and will
end at E. the algorithm uses two queues,
namely QUEUE1 and QUEUE2. QUEUE1 holds all the nodes that are to be processed while QUEUE2 holds
all the nodes that are processed and deleted from QUEUE1.

Lets start examining the graph from Node A.

1. Add A to QUEUE1 and NULL to QUEUE2.

1. QUEUE1 = {A}
2. QUEUE2 = {NULL}

2. Delete the Node A from QUEUE1 and insert all its neighbours. Insert Node A into QUEUE2

1. QUEUE1 = {B, D}
2. QUEUE2 = {A}

3. Delete the node B from QUEUE1 and insert all its neighbours. Insert node B into QUEUE2.
1. QUEUE1 = {D, C, F}
2. QUEUE2 = {A, B}

4. Delete the node D from QUEUE1 and insert all its neighbours. Since F is the only neighbour of it which has
been inserted, we will not insert it again. Insert node D into QUEUE2.

1. QUEUE1 = {C, F}
2. QUEUE2 = { A, B, D}

5. Delete the node C from QUEUE1 and insert all its neighbours. Add node C to QUEUE2.

1. QUEUE1 = {F, E, G}
2. QUEUE2 = {A, B, D, C}

6. Remove F from QUEUE1 and add all its neighbours. Since all of its neighbours has already been added,
we will not add them again. Add node F to QUEUE2.

1. QUEUE1 = {E, G}
2. QUEUE2 = {A, B, D, C, F}

7. Remove E from QUEUE1, all of E's neighbours has already been added to QUEUE1 therefore we will not
add them again. All the nodes are visited and the target node i.e. E is encountered into QUEUE2.

1. QUEUE1 = {G}
2. QUEUE2 = {A, B, D, C, F, E}

Graph Traversal - DFS

DFS (Depth First Search)

DFS traversal of a graph produces a spanning tree as final result. Spanning Tree is a graph

without loops. We use Stack data structure with maximum size of total number of vertices in

the graph to implement DFS traversal.

We use the following steps to implement DFS traversal...


 Step 1 - Define a Stack of size total number of vertices in the graph.

 Step 2 - Select any vertex as starting point for traversal. Visit that vertex and push it on

to the Stack.

 Step 3 - Visit any one of the non-visited adjacent vertices of a vertex which is at the top

of stack and push it on to the stack.

 Step 4 - Repeat step 3 until there is no new vertex to be visited from the vertex which

is at the top of the stack.

 Step 5 - When there is no new vertex to visit then use back tracking and pop one

vertex from the stack.

 Step 6 - Repeat steps 3, 4 and 5 until stack becomes Empty.

 Step 7 - When stack becomes Empty, then produce final spanning tree by

removing unused edges from the graph

Back tracking is coming back to the vertex from which we reached the current vertex.

Example
Example

Stack
status:

Output:

Stack status: A

B Output: A B
Stack status: A S

C Output: A B S

Stack status: A S C D

Output: A B S C
Stack status: A S

C Output: A B S C

Stack status: A S C E

Output: A B S D E
Stack status: A S C E H

Output: A B S D E H

Stack status: A S C E H G

Output: A B S D E H G
Stack status: A S C E H G F

Output: A B S C D E H G F

Stack status: A S C E H G

Output: A B S C D E H G F
Stack status:

Output: A B S C D E H G F

Example 3
Consider the graph G along with its adjacency list, given in the figure below. Calculate the
order to print all the nodes of the graph starting from node H, by using depth first search (DFS)
algorithm.

Solution :
Push H onto the stack

1. STACK : H

POP the top element of the stack i.e. H, print it and push all the neighbours of H onto the stack that are is
ready state.

1. Print H
2. STACK : A

Pop the top element of the stack i.e. A, print it and push all the neighbours of A onto the stack that are in
ready state.

1. Print A
2. Stack : B, D

Pop the top element of the stack i.e. D, print it and push all the neighbours of D onto the stack that are in
ready state.

1. Print D
2. Stack : B, F
Pop the top element of the stack i.e. F, print it and push all the neighbours of F onto the stack that
are in ready state.

1. Print F
2. Stack : B

Pop the top of the stack i.e. B and push all the neighbours

1. Print B
2. Stack : C

Pop the top of the stack i.e. C and push all the neighbors.

1. Print C
2. Stack : E, G

Pop the top of the stack i.e. G and push all its neighbors.

1. Print G
2. Stack : E

Pop the top of the stack i.e. E and push all its neighbors.

1. Print E
2. Stack :

Hence, the stack now becomes empty and all the nodes of the graph have been traversed.

The printing sequence of the graph will be :

H→ A→ D→ F→ B→ C→ G→ E

Spanning Tree
Spanning tree can be defined as a sub-graph of connected, undirected graph G that is a tree
produced by removing the desired number of edges from a graph. In other words, Spanning
tree is a non-cyclic sub-graph of a connected and undirected graph G that connects all the
vertices together. A graph G can have multiple spanning trees.
Minimum Spanning Tree
There can be weights assigned to every edge in a weighted graph. However, A minimum
spanning tree is a spanning tree which has minimal total weight. In other words, minimum
spanning tree is the one which contains the least weight among all other spanning tree of some
particular graph.

What is a Spanning Tree?

Given an undirected and connected graph G=(V,E), a spanning tree of the graph G is a
tree that spans G (that is, it includes every vertex of G) and is a subgraph of G (every
edge in the tree belongs to G)

What is a Minimum Spanning Tree?

The cost of the spanning tree is the sum of the weights of all the edges in the tree. There can
be many spanning trees. Minimum spanning tree is the spanning tree where the cost is
minimum among all the spanning trees. There also can be many minimum spanning trees.

Minimum spanning tree has direct application in the design of networks. It is used in
algorithms approximating the travelling salesman problem, multi-terminal minimum cut
problem and minimum-cost weighted perfect matching. Other practical applications are:

1. Cluster Analysis
2. Handwriting recognition
3. Image segmentation
Shortest path algorithms
In this section, we will discuss the algorithms to calculate the shortest path between
two nodes in a graph.

There are two algorithms which are being used for this purpose. Prim's

Algorithm

Kruskal's Algorithm

Prim's Algorithm

• Prim’s Algorithm is greedy algorithm used for finding the Minimum


Spanning Tree (MST) of a given graph.

• The graph must be weighted, connected and undirected.


Prim's algorithm starts with the single node and explore all the adjacent nodes with all the
connecting edges at every step. The edges with the minimal weights causing no cycles in the
graph got selected.

The algorithm is given as follows.


Algorithm

Step 1: Select a starting vertex

Step 2: Repeat Steps 3 and 4 until there are fringe vertices

Step 3: Select an edge e connecting the tree vertex and fringe vertex that has minimum
weight , If including that edge creates a cycle, then reject that edge and look for the next least
weight edge.

Step 4: Add the selected edge and the vertex to the minimum spanning tree T [END OF LOOP]

Step 5: EXIT Time

Complexity-

Worst case time complexity of Prim’s Algorithm

= O(ElogV) using binary heap

= O(E + VlogV) using Fibonacci heap

Explanation-

If adjacency list is used to represent the graph, then using breadth first search, all the vertices
can be traversed in O(V + E) time.

We traverse all the vertices of graph using breadth first search and use a min heap for storing
the vertices not yet included in the MST.

To get the minimum weight edge, we use min heap as a priority queue.

Min heap operations like extracting minimum element and decreasing key value takes O(logV)
time.

So, overall time complexity


= O(E + V) x O(logV)

= O((E + V)logV)

= O(ElogV)

This time complexity can be improved and reduced to O(E + VlogV) using Fibonacci heap.

Problem-01:

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

Solution-
Since all the vertices have been included in the MST, so we stop. Weight of

the MST

= Sum of all edge weights

= 10 + 25 + 22 + 12 + 16 + 14

= 99 units

Problem-02:

Construct the minimum spanning tree (MST) for the given graph using Prim’s Algorithm-
The Minimum Spanning Tree (MST) obtained by the application of Prim’s Algorithm on given
graph is-

Weight of the MST

= Sum of all edge weights

= 1 + 4 + 2 + 6 + 3 + 10

= 26 units

Example3
MST=14

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. Kruskal's algorithm follows greedy approach which finds an optimum
solution at every stage instead of focusing on a global optimum.

The Kruskal's algorithm is given as follows.

Step-01:
Sort all the edges from low weight to high weight.

Step-02:
Take the edge with the lowest weight and use it to connect the vertices of graph.

If adding an edge creates a cycle, then reject that edge and go for the next least weight edge.
Step-03:
Keep adding edges until all the vertices are connected and a Minimum Spanning Tree (MST) is
obtained.

Time Complexity-

Worst case time complexity of Kruskal’s Algorithm = O(ElogV) or O(ElogE). Explanation-

• The edges are maintained as min heap.

• The next edge can be obtained in O(logE) time if graph has E edges.

• Reconstruction of heap takes O(E) time.

• So, Kruskal’s Algorithm takes O(ElogE) time.

• The value of E can be at most O(V2). So, O(logV) and O(logE) are same.

Special Case-

• If the edges are already sorted, then there is no need to construct min heap.

• So, deletion from min heap time is saved.

• In this case, time complexity of Kruskal’s Algorithm = O(E + V)

Construct the minimum spanning tree (MST) for the given graph using Kruskal’s Algorithm-
Since all the vertices have been included in the MST, so we stop. Weight of

the MST

= Sum of all edge weights

= 10 + 25 + 22 + 12 + 16 + 14

= 99 units
Apply the Kruskal's algorithm on the graph given as follows.
The next step is to add AE, but we can't add that as it will cause a cycle. The next edge

to be added is AC, but it can't be added as it will cause a cycle.

The next edge to be added is AD, but it can't be added as it will contain a cycle. Hence, the

final MST is the one which is shown in the step 4.

the cost of MST = 1 + 2 + 3 + 4 = 10.


Which algorithm is preferred- Prim’s Algorithm or Kruskal’s Algorithm?

Solution-

• Kruskal’s Algorithm is preferred when the graph is sparse i.e. when there are
less number of edges in the graph like E = O(V) or when the edges are already
sorted or can be sorted in linear time.

• Prim’s Algorithm is preferred when the graph is dense i.e. when there are
large number of edges in the graph like E = O(V2) because we do not have to
pay much attention to the cycles by adding an edge as we primarily deal with
the vertices in Prim’s Algorithm.

Q2:Will both Prim’s Algorithm and Kruskal’s Algorithm always produce the same
Minimum Spanning Tree (MST) for any given graph?
Solution-

The following two cases are possible-

Case-01: When all the edge weights are distinct-

If all the edge weights are distinct, then both the algorithms are guaranteed to find the same
i.e. unique MST.

Example-

Consider the following example-


The application of both the algorithms on the above graph will produce the same MST as
shown.

This example clearly illustrates when all the edge weights are distinct, both the algorithms
always produces the same MST having the same cost as shown.

Case-02: When all the edge weights are not distinct-

If all the edge weights are not distinct, then both the algorithms may not always produce the
same i.e. unique MST but the cost of the MST produced would always be same in both the
cases.

Example-

Consider the following example-


NGIT DSA 2023 UNIT-V Lecture Notes

This example clearly illustrates when in the given graph, all the edge weights are not
distinct, different MSTs could be produced by both the algorithms as shown but the
cost of the resulting MSTs from both the algorithms would always be same.

(Searching and Sorting)


Linear Search Algorithm

What is Search?

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
Search is a process of finding a value in a list of values. In other words, searching is the
process of locating given value position in a list of values.

Linear Search Algorithm (Sequential Search Algorithm)


Linear search algorithm finds given element in a list of elements with O(n) time complexity
where n is total number of elements in the list. This search process starts comparing of
search element with the first element in the list. If both are matching then results with
element found otherwise search element is compared with next element in the list. If both
are matched, then the result is "element found". Otherwise, repeat the same with the next
element in the list until search element is compared with last element in the list, if that last
element also doesn't match, then the result is "Element not found in the list". That means,
the search element is compared with element by element in the list.

Linear search is implemented using following steps...

 Step 1: Read the search element from the user

 Step 2: Compare, the search element with the first element in the list.

 Step 3: If both are matching, then display "Given element found!!!" and terminate

the function

 Step 4: If both are not matching, then compare search element with the next

element in the list.

 Step 5: Repeat steps 3 and 4 until the search element is compared with the last

element in the list.

 Step 6: If the last element in the list is also doesn't match, then display "Element not

found!!!" and terminate the function.


Example
Consider the following list of element and search element...

Linear Search Program in C Programming Language


#include<stdio.h>
#include<conio.h>

void main(){
int list[20],size,i,sElement;

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes

printf("Enter size of the list: ");


scanf("%d",&size);

printf("Enter any %d integer values: ",size);


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

printf("Enter the element to be Search: ");


scanf("%d",&sElement);

// Linear Search Logic


for(i = 0; i < size; i++)
{
if(sElement == list[i])
{
printf("Element is found at %d index", i);
break;
}
}
if(i == size)
printf("Given element is not found in the list!!!");
getch();
}

Binary Search Algorithm

What is Search?
Search is a process of finding a value in a list of values. In other words, searching is the
process of locating given value position in a list of values.

Binary Search Algorithm


Binary search algorithm finds given element in a list of elements with O(log n) time
complexity where n is total number of elements in the list. The binary search algorithm can
be used with only sorted list of element. That means, binary search can be used only with
lkist of element which are already arraged in a order. The binary search can not be used for
list of element which are in random order. This search process starts comparing of the
search element with the middle element in the list. If both are matched, then the result is

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
"element found". Otherwise, we check whether the search element is smaller or larger than
the middle element in the list. If the search element is smaller, then we repeat the same
process for left sublist of the middle element. If the search element is larger, then we repeat
the same process for right sublist of the middle element. We repeat this process until we
find the search element in the list or until we left with a sublist of only one element. And if
that element also doesn't match with the search element, then the result is "Element not
found in the list".

Binary search is implemented using following steps...

 Step 1: Read the search element from the user

 Step 2: Find the middle element in the sorted list

 Step 3: Compare, the search element with the middle element in the sorted list.

 Step 4: If both are matching, then display "Given element found!!!" and terminate

the function

 Step 5: If both are not matching, then check whether the search element is smaller

or larger than middle element.

 Step 6: If the search element is smaller than middle element, then repeat steps 2, 3,

4 and 5 for the left sublist of the middle element.

 Step 7: If the search element is larger than middle element, then repeat steps 2, 3, 4

and 5 for the right sublist of the middle element.

 Step 8: Repeat the same process until we find the search element in the list or until

sublist contains only one element.

 Step 9: If that element also doesn't match with the search element, then display

"Element not found in the list!!!" and terminate the function.


Example
Consider the following list of element and search element...

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
Binary Search Program in C Programming Language
#include<stdio.h>
#include<conio.h>

void main()
{
int first, last, middle, size, i, sElement, list[100];
clrscr();

printf("Enter the size of the list: ");


scanf("%d",&size);

printf("Enter %d integer values in Assending order\n", size);

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


scanf("%d",&list[i]);

printf("Enter value to be search: ");


scanf("%d", &sElement);

first = 0;
last = size - 1;
middle = (first+last)/2;

while (first <= last) {


if (list[middle] < sElement)
first = middle + 1;
else if (list[middle] == sElement) {
printf("Element found at index %d.\n",middle);
break;
}
else
last = middle - 1;

middle = (first + last)/2;

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
}
if (first > last)
printf("Element Not found in the list.");
getch();
}

Insertion Sort

Sorting is the process of arranging a list of elements in a particular order (Ascending or


Descending).

Insertion sort algorithm arranges a list of elements in a particular order. In insertion sort
algorithm, every iteration moves an element from unsorted portion to sorted portion until
all the elements are sorted in the list.

Step by Step Process


The insertion sort algorithm is performed using following steps...

 Step 1: Asume that first element in the list is in sorted portion of the list and

remaining all elements are in unsorted portion.

 Step 2: Consider first element from the unsorted list and insert that element into the

sorted list in order specified.

 Step 3: Repeat the above process until all the elements from the unsorted list are

moved into the sorted list.

Sorting Logic
Following is the sample code for insrtion sort...

//Insertion sort logic


for i = 1 to size-1 {
temp = list[i];

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
j = i;
while ((temp < list[j]) && (j > 0)) {
list[j] = list[j-1];
j = j - 1;
}
list[j] = temp;
}

Example

Complexity of the Insertion Sort Algorithm


To sort a unsorted list with 'n' number of elements we need to make (1+2+3+......+n-1) = (n
(n-1))/2 number of comparisions in the worst case. If the list already sorted, then it
requires 'n' number of comparisions.
WorstCase: O(n2)
BestCase: Ω(n)
Average Case : Θ(n2)

Insertion Sort Program in C Programming Language


#include<stdio.h>
#include<conio.h>

void main(){

int size, i, j, temp, list[100];

printf("Enter the size of the list: ");


scanf("%d", &size);

printf("Enter %d integer values: ", size);


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

//Insertion sort logic


for (i = 1; i < size; i++) {
temp = list[i];
j = i - 1;
while ((temp < list[j]) && (j >= 0)) {
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes
list[j + 1] = list[j];
j = j - 1;
}
list[j + 1] = temp;
}

printf("List after Sorting is: ");


for (i = 0; i < size; i++)
printf(" %d", list[i]);

getch();
}

Selection Sort

Selection Sort algorithm is used to arrange a list of elements in a particular order


(Ascending or Descending). In selection sort, the first element in the list is selected and it is
compared repeatedly with remaining all the elements in the list. If any element is smaller
than the selected element (for Ascending order), then both are swapped. Then we select
the element at second position in the list and it is compared with remaining all elements in
the list. If any element is smaller than the selected element, then both are swapped. This
procedure is repeated till the entire list is sorted.

Step by Step Process


The selection sort algorithm is performed using following steps...

 Step 1: Select the first element of the list (i.e., Element at first position in the list).

 Step 2: Compare the selected element with all other elements in the list.

 Step 3: For every comparision, if any element is smaller than selected element (for

Ascending order), then these two are swapped.

 Step 4: Repeat the same procedure with next position in the list till the entire list is

sorted.

Sorting Logic
Following is the sample code for selection sort...

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
//Selection sort logic

for(i=0; i<size; i++){


for(j=i+1; j<size; j++){
if(list[i] > list[j])
{
temp=list[i];
list[i]=list[j];
list[j]=temp;
}
}
}

Example

Complexity of the Insertion Sort Algorithm


To sort a unsorted list with 'n' number of elements we need to make ((n-1)+(n-2)+(n-3)+......
+1) = (n (n-1))/2 number of comparisions in the worst case. If the list already sorted, then it
requires 'n' number of comparisions.
Worst Case : O(n2)
Best Case : Ω(n2)
Average Case : Θ(n2)

Selection Sort Program in C Programming Language


#include<stdio.h>
#include<conio.h>
void main(){

int size,i,j,temp,list[100];
clrscr();

printf("Enter the size of the List: ");


scanf("%d",&size);

printf("Enter %d integer values: ",size);


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

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
//Selection sort logic

for(i=0; i<size; i++){


for(j=i+1; j<size; j++){
if(list[i] > list[j])
{
temp=list[i];
list[i]=list[j];
list[j]=temp;
}
}
}

printf("List after sorting is: ");


for(i=0; i<size; i++)
printf(" %d",list[i]);

getch();
}

Quick Sort
Quick Sort

Quick Sort Program in C Programming Language


#include<stdio.h>
#include<conio.h>
void quickSort(int [10],int,int);
void main(){
int list[20],size,i;
printf("Enter size of the list: ");
scanf("%d",&size);
printf("Enter %d integer values: ",size);
for(i = 0; i < size; i++)
scanf("%d",&list[i]);

quicksort(list,0,size-1);
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes

printf("List after sorting is: ");


for(i = 0; i < size; i++)
printf(" %d",list[i]);

getch();
}

void quickSort(int list[10],int first,int last){


int pivot,i,j,temp;
if(first < last){
pivot = first;
i = first;
j = last;

while(i < j){


while(list[i] <= list[pivot] && i < last)
i++;
while(list[j] > list[pivot])
j--;
if(i < j){
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
temp = list[pivot];
list[pivot] = list[j];
list[j] = temp;
quickSort(list,first,j-1);
quickSort(list,j+1,last);

}
}

Merge Sort
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes

ALGORITHM:

If r > l
1. Find the middle point to divide the array into two halves:
middle m = (l+r)/2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2 and 3:
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes
Call merge(arr, l, m, r)
#include <stdio.h>
#include <stdlib.h>

void merge(int arr[], int l, int m, int r)


{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;

int L[n1], R[n2];

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


L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];

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

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}

while (j < n2) {


arr[k] = R[j];
j++;
k++;
}
}

void mergeSort(int arr[], int l, int r)


{
if (l < r) {

int m = l + (r - l) / 2;

mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);

merge(arr, l, m, r);
}
}

// main function
void main() {
int n;
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes
scanf("%d",&n);
int data[n];
for(int i=0;i<n;i++)
{
scanf("%d",&data[i]);
}
mergeSort(data, 0, n - 1);
for (int i = 0; i < n; ++i) {
printf("%d ", data[i]);
}
}

Heap Sort

#include <stdio.h>
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes
*b = temp;
}
void heapify(int arr[], int N, int i)
{
int largest = i;
int left = 2 * i + 1;
int 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)
{
swap(&arr[i], &arr[largest]);
heapify(arr, N, largest);
}
}
void heapSort(int arr[], int N)
{
int i,temp;
for (i = N / 2 - 1; i >= 0; i--)
heapify(arr, N, i);
for (i = N - 1; i >= 0; i--)
{
swap(&arr[0], &arr[i]);
heapify(arr, i, 0);
}
}
int main()
{
int n,i;
scanf("%d",&n);
int arr[n];
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
heapSort(arr, n);
Suthoju Girija Rani – [email protected]
NGIT DSA 2023 UNIT-V Lecture Notes
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
}

Shell Sort
Shell sort is a highly efficient sorting algorithm and is based on insertion sort algorithm. This
algorithm avoids large shifts as in case of insertion sort, if the smaller value is to the far right
and has to be moved to the far left.

This algorithm uses insertion sort on a widely spread elements, first to sort them and then
sorts the less widely spaced elements. This spacing is termed as interval. This interval is
calculated based on Knuth's formula as −

Knuth's Formula
h=h*3+1
where −
h is interval with initial value 1
This algorithm is quite efficient for medium-sized data sets as its average and worst-case
complexity of this algorithm depends on the gap sequence the best known is Ο(n), where n
is the number of items. And the worst case space complexity is O(n).

We compare values in each sub-list and swap them (if necessary) in the original
array. After this step, the new array should look like this −

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes
Then, we take interval of 1 and this gap generates two sub-lists - {14, 27, 35, 42},
{19, 10, 33, 44}

We compare and swap the values, if required, in the original array. After this step,
the array should look like this −

Finally, we sort the rest of the array using interval of value 1. Shell sort uses
insertion sort to sort the array.

Following is the step-by-step depiction −

Suthoju Girija Rani – [email protected]


NGIT DSA 2023 UNIT-V Lecture Notes

We see that it required only four swaps to sort the rest of the array.

Algorithm

Following is the algorithm for shell sort.

Step 1 − Initialize the value of h


Step 2 − Divide the list into smaller sub-list of equal interval h
Step 3 − Sort these sub-lists using insertion sort
Step 3 − Repeat until complete list is sorted

Suthoju Girija Rani – [email protected]

You might also like