0% found this document useful (0 votes)
4 views135 pages

Sorting Algorithms

The document provides an overview of sorting algorithms, detailing their definitions, types, and characteristics. It explains in-place sorting, internal and external sorting, and the concepts of stability in sorting. Additionally, it covers specific algorithms such as Bubble Sort, Selection Sort, and Insertion Sort, including their workings, applications, and example implementations in C.

Uploaded by

aman09052004
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)
4 views135 pages

Sorting Algorithms

The document provides an overview of sorting algorithms, detailing their definitions, types, and characteristics. It explains in-place sorting, internal and external sorting, and the concepts of stability in sorting. Additionally, it covers specific algorithms such as Bubble Sort, Selection Sort, and Insertion Sort, including their workings, applications, and example implementations in C.

Uploaded by

aman09052004
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
You are on page 1/ 135

Sorting Algorithms

Harshita Sharma
Delhi Technological University
Department of CSE
INTRODUCTION
What is sorting?
• A Sorting Algorithm is used to rearrange a given array or list elements
according to a comparison operator on the elements. The comparison
operator is used to decide the new order of elements in the
respective data structue
Sorting Terminology
• What is in-place sorting? An in-place sorting algorithm uses constant
space for producing the output (modifies the given array only). It
sorts the list only by modifying the order of the elements within the
list. For example, Insertion Sort and Selection Sorts are in-place
sorting algorithms as they do not use any additional space for sorting
the list
Types of Sorting
• Internal Sorting :
• When all data is placed in the main memory or internal memory then sorting is called
internal sorting.
• In internal sorting, the problem cannot take input beyond its size.
• Example: heap sort, bubble sort, selection sort, quick sort, shell sort, insertion sort.
• External Sorting :
• When all data that needs to be sorted cannot be placed in memory at a time, the sorting
is called external sorting. External Sorting is used for the massive amount of data.
• Merge Sort and its variations are typically used for external sorting.
• Some external storage like hard disks and CDs are used for external sorting.
• Example: Merge sort, Tag sort, Polyphase sort, Four tape sort, External radix sort,
Internal merge sort, etc.
Stability in sorting
• What is stable sorting?
• When two same data appear in the same order in sorted data
without changing their position is called stable sort.
• Example: merge sort, insertion sort, bubble sort.
• What is Unstable sorting?
• When two same data appear in the different order in sorted data it
is called unstable sort.
• Example: quick sort, heap sort, shell sort.
BUBBLE SORT
Introduction
• Bubble Sort is the simplest sorting algorithm that works by
repeatedly swapping the adjacent elements if they are in the wrong
order. This algorithm is not suitable for large data sets.
• After each iteration the heaviest element bubbles down or settles at
the end of the array. The next iteration or pass over the array does
not consider the already bubbled down elements at the array end.
• It is in-place and stable sorting algorithm.
• Bubble sort algorithm repeatedly compares the adjacent elements
and swaps them if not in order.
• Bubble Sort Applications
• Bubble sort is used if
• complexity does not matter
• short and simple code is preferred
• Since it compares all the elements one by one, bubble sort is a slow
algorithm and performs inefficiently in real-world scenarios. It is
generally used for educational purposes or to determine if the sorted
given list is already sorted or not.
• In bubble sort, to sort a list of size n, we need to perform n –
1 iterations.
Working
• Consider that we want to sort a list in ascending order, here are the
steps that the algorithm would follow:
• Start with the first element.
• Compare the current element with the next element.
• If the current element is greater than the next element, then swap
both the elements. If not, move to the next element.
• Repeat steps 1 – 3 until we get the sorted list. To better understand
bubble sort, recall the list that contains the elements 5, 3, 4,
2 initially.
Example 1
• Consider an array arr[] = {5, 1, 4, 2, 8}
• First Pass:
• Bubble sort starts with very first two elements, comparing them to
check which one is greater.
• ( 5 1 4 2 8 ) –> ( 1 5 4 2 8 ), Here, algorithm compares the first two elements,
and swaps since 5 > 1.
• ( 1 5 4 2 8 ) –> ( 1 4 5 2 8 ), Swap since 5 > 4
• ( 1 4 5 2 8 ) –> ( 1 4 2 5 8 ), Swap since 5 > 2
• ( 1 4 2 5 8 ) –> ( 1 4 2 5 8 ), Now, since these elements are already in order (8 >
5), algorithm does not swap them.
• Second Pass:
• Now, during second iteration it should look like this:
• ( 1 4 2 5 8 ) –> ( 1 4 2 5 8 )
• ( 1 4 2 5 8 ) –> ( 1 2 4 5 8 ), Swap since 4 > 2
• ( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
• ( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
• Third Pass:
• Now, the array is already sorted, but our algorithm does not know if it
is completed.
• The algorithm needs one whole pass without any swap to know it is
sorted.
• ( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
• ( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
• ( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
• ( 1 2 4 5 8 ) –> ( 1 2 4 5 8 )
Example 2
Algorithm
• Bubble Sort Algorithm
• We know that to sort a list of n elements using bubble sort, we need
to perform n – 1 iterations. And for each iteration, we need to:
• Run a loop over the entire list or array.
• Compare the element at the index i with the element at i + 1.
• If the element at i is greater than the element at i + 1, swap both the
elements
• Else, move to the next element.
begin bubbleSort(list)

for i = 0 to sizeof(list) - 1

for j = 0 to sizeof(list) - (i - 1)
if list[j] > list[j+1]
swap(list[i], list[i+1])
end if
end for

end for

end bubbleSort
Flowchart
C Code
// C program for implementation of Bubble sort
#include <stdio.h>

void swap(int* xp, int* yp)


{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)

// Last i elements are already in place


for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
// Driver program to test above functions
int main()
{
int arr[] = { 64, 34, 25, 12, 22, 11, 90 };
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}
Output

Sorted array: 1 2 3 4 5 7 8 9
SELECTION SORT
Introduction
• The selection sort algorithm sorts an array by repeatedly finding the
minimum element (considering ascending order) from unsorted part and
putting it at the beginning. The algorithm maintains two subarrays in a
given array.
• The subarray which is already sorted.
• Remaining subarray which is unsorted.
• In every iteration of selection sort, the minimum element (considering
ascending order) from the unsorted subarray is picked and moved to the
sorted subarray.
• In selection sort, with each iteration over the unsorted sublist, only one
element is sorted.
• We know that to sort a list of n elements using selection sort, we need to
perform n – 1 iterations.
• Selection sort is a sorting algorithm. This sorting algorithm is an in-place
comparison-based algorithm in which the list is divided into two parts, the
sorted part at the left end and the unsorted part at the right end. Initially,
the sorted part is empty, and the unsorted part is the entire list.
• Selection Sort Applications
• The selection sort is used when
• a small list is to be sorted
• cost of swapping does not matter
• checking of all the elements is compulsory
• cost of writing to a memory matters like in flash memory
Working
Now, let us consider that we want to sort a list in ascending order. Here are
the steps that the algorithm would follow:
• Start with the first element. At this point, the entire list is unsorted. And
the sorted sublist is empty.
• Iterate over the list to search for the smallest element in it.
• Add this element to the sorted sublist, and remove it from the unsorted
sublist. In other words, swap the smallest element in the unsorted sublist
with the element that is present at its correct sorted position.
• Repeat the above steps until all the elements from the unsorted sublist are
transferred to the sorted sublist.
Example 1
• Lets consider the following array as an example: arr[] = {64, 25, 12,
22, 11}
• First pass:
• For the first position in the sorted array, the whole array is traversed
from index 0 to 4 sequentially. The first position where 64 is stored
presently, after traversing whole array it is clear that 11 is the lowest
value.
64 25 12 22 11
• Thus, replace 64 with 11. After one iteration 11, which happens to be
the least value in the array, tends to appear in the first position of the
sorted list.

11 25 12 22 64
• Second Pass:
• For the second position, where 25 is present, again traverse the rest of
the array in a sequential manner.

11 25 12 22 64

• After traversing, we found that 12 is the second lowest value in the


array and it should appear at the second place in the array, thus swap
these values.
11 12 25 22 64
• Third Pass:
• Now, for third place, where 25 is present again traverse the rest of the
array and find the third least value present in the array.
11 12 25 22 64

• While traversing, 22 came out to be the third least value and it should
appear at the third place in the array, thus swap 22 with element
present at third position.
11 12 22 25 64
• Fourth pass:
• Similarly, for fourth position traverse the rest of the array and find the
fourth least element in the array
• As 25 is the 4th lowest value hence, it will place at the fourth position.

11 12 22 25 64
• Fifth Pass:
• At last the largest value present in the array automatically get placed
at the last position in the array
• The resulted array is the sorted array.

11 12 22 25 64
Example 2
Approach
• Initialize minimum value(min_idx) to location 0
• Traverse the array to find the minimum element in the array
• While traversing if any element smaller than min_idx is found then
swap both the values.
• Then, increment min_idx to point to next element
• Repeat until array is sorted
Algorithm
• Run a loop from i = 0 till the size of the list. Under the loop –
• Declare a variable called minIndex. minIndex helps in tracking the index of the
next element that will be swapped with the element at the index i.
• Run a nested for loop from j = i + 1 till the size of the list. We initialize j with i +
1 since it allows us to reduce the number of total comparisons made. Under
this loop –
• Check if the element at the index j is smaller than the element at the index mid_index. If
it is, set minIndex equal to j. It helps us in searching for the smallest element in the
unsorted sublist.
• Swap the element at the index i with the element at index minIndex. It allows us to place
the smallest element from the unsorted sublist at the end of the sorted sublist. Note
that we are updating the value of minIndex each time we find an element smaller than
it.
begin selectionSort(list)
for i = 0 to sizeof(list) - 1

minIndex = i;

for j = i + 1 to sizeof(list)

if list[j] < list[mid_index]


minIndex = j;
end if

swap(list[minIndex], list[i])

end for

end for
end selectionSort
Flowchart
C Code
// C program for implementation of selection sort
#include <stdio.h>

void swap(int *xp, int *yp)


{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, min_idx;

// One by one move boundary of unsorted subarray


for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;

// Swap the found minimum element with the first element


swap(&arr[min_idx], &arr[i]);
}
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
// Driver program to test above functions
int main()
{
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr)/sizeof(arr[0]);
selectionSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);
return 0;
}
Output

Sorted array: 11 12 22 25 64
INSERTION SORT
Introduction
• Insertion sort is a simple sorting algorithm that works similar to the way
you sort playing cards in your hands. The array is virtually split into a sorted
and an unsorted part. Values from the unsorted part are picked and placed
at the correct position in the sorted part.
• Insertion sort is a sorting algorithm in which the elements are transferred
one at a time to the right position.
• Characteristics of Insertion Sort:
• This algorithm is one of the simplest algorithm with simple implementation
• Basically, Insertion sort is efficient for small data values
• Insertion sort is adaptive in nature, i.e. it is appropriate for data sets which
are already partially sorted.
• Insertion sort works similarly as we sort cards in our hand in a card
game.
• We assume that the first card is already sorted then, we select an
unsorted card. If the unsorted card is greater than the card in hand, it
is placed on the right otherwise, to the left. In the same way, other
unsorted cards are taken and put in their right place.
• Insertion Sort Applications
• The insertion sort is used when:
• the array is has a small number of elements
• there are only a few elements left to be sorted
Working
• We pick one element at a time, compare it against all elements on one side of it(e.g. left) and
place this into the correct place.
• E.g. if elements were in order: 3, 5, 2
• You can start by picking 3, and since there is no element to the left of 3, we can assume it is in the
correct place. Array: 3, 5, 2
• You can pick 5, you compare 5 with 3, and you find 5 is in the correct order amongst the array
of [3, 5]. Array: 3, 5, 2 Then you pick 2, you find the place in the left side array of [3,5] to place
this 2. Since 2 must come before 3, we insert 2 before 3. Array: 2, 3, 5 → Which is a sorted order.
• So, if you must notice, whenever we pick a new element, all elements to the left of it are already
sorted(highlighted as green). Think of it analogous to the left hand while sorting the deck of
cards, which carries sorted cards. We just compare in the left sorted half to find the place to place
this element. We place this at that position and shift all other elements.
• If we continue this till the end, we will get up to the last element placed in the correct position,
i.e. the entire array will be sorted.
Example 1
• Consider an example: arr[]: {12, 11, 13, 5, 6}
• First Pass:
• Initially, the first two elements of the array are compared in insertion
sort.
12 11 13 5 6

• Here, 12 is greater than 11 hence they are not in the ascending order
and 12 is not at its correct position. Thus, swap 11 and 12.
• So, for now 11 is stored in a sorted sub-array.
11 12 13 5 6
• Second Pass:
• Now, move to the next two elements and compare them

11 12 13 5 6

• Here, 13 is greater than 12, thus both elements seems to be in


ascending order, hence, no swapping will occur. 12 also stored in a
sorted sub-array along with 11
• Third Pass:
• Now, two elements are present in the sorted sub-array which
are 11 and 12
• Moving forward to the next two elements which are 13 and 5
11 12 13 5 6

• Both 5 and 13 are not present at their correct place so swap them

11 12 5 13 6
• After swapping, elements 12 and 5 are not sorted, thus swap again

11 5 12 13 6

• Here, again 11 and 5 are not sorted, hence swap again

5 11 12 13 6

here, it is at its correct position


• Fourth Pass:
• Now, the elements which are present in the sorted sub-array are 5,
11 and 12
• Moving to the next two elements 13 and 6

5 11 12 13 6

• Clearly, they are not sorted, thus perform swap between both

5 11 12 6 13
• Now, 6 is smaller than 12, hence, swap again
5 11 6 12 13

• Here, also swapping makes 11 and 6 unsorted hence, swap again

5 6 11 12 13

• Finally, the array is completely sorted.


Illustration
Example 2
Algorithm
• To sort an array of size N in ascending order:
• Iterate from arr[1] to arr[N] over the array.
• Compare the current element (key) to its predecessor.
• If the key element is smaller than its predecessor, compare it to the
elements before. Move the greater elements one position up to make
space for the swapped element.
insertionSort(array)
mark First element as sorted
for each unsorted element E
‘extract’ the element E
for j <- lastSortedIndex down to 0
if current element j > E
move sorted element to the right by 1
break loop and insert E here
end InsertionSort
Flowchart
C Code
// C program for insertion sort
#include <math.h>
#include <stdio.h>

/* Function to sort an array using insertion sort*/


void insertionSort(int arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++) {
key = arr[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// A utility function to print an array of size n
void printArray(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
/* Driver program to test insertion sort */
int main()
{
int arr[] = { 12, 11, 13, 5, 6 };
int n = sizeof(arr) / sizeof(arr[0]);

insertionSort(arr, n);
printArray(arr, n);

return 0;
}
Output

5 6 11 12 13
MERGE SORT
Introduction
• The Merge Sort algorithm is a sorting algorithm that is considered an
example of the divide and conquer strategy. So, in this algorithm, the
array is initially divided into two equal halves and then they are
combined in a sorted manner. We can think of it as a recursive
algorithm that continuously splits the array in half until it cannot be
further divided. This means that if the array becomes empty or has
only one element left, the dividing will stop, i.e. it is the base case to
stop the recursion. If the array has multiple elements, we split the
array into halves and recursively invoke the merge sort on each of the
halves. Finally, when both the halves are sorted, the merge operation
is applied. Merge operation is the process of taking two smaller
sorted arrays and combining them to eventually make a larger one.
• Merge Sort Applications
• Inversion count problem
• External sorting
• E-commerce applications
Merge sort in stable but not in-place sorting.
• Drawbacks of Merge Sort:
• Slower comparative to the other sort algorithms for smaller tasks.
• The merge sort algorithm requires an additional memory space of 0(n) for
the temporary array.
• It goes through the whole process even if the array is sorted.
Divide and Conquer Strategy
• Using the Divide and Conquer technique, we divide a problem into
subproblems. When the solution to each subproblem is ready, we
'combine' the results from the subproblems to solve the main
problem.
• Suppose we had to sort an array A. A subproblem would be to sort a
sub-section of this array starting at index p and ending at index r,
denoted as A[p..r].
• Divide
• If q is the half-way point between p and r, then we can split the
subarray A[p..r] into two arrays A[p..q] and A[q+1, r].
• Conquer
• In the conquer step, we try to sort both the subarrays A[p..q] and A[q+1, r].
If we haven't yet reached the base case, we again divide both these
subarrays and try to sort them.
• Combine
• When the conquer step reaches the base step and we get two sorted
subarrays A[p..q] and A[q+1, r] for array A[p..r], we combine the results by
creating a sorted array A[p..r] from two sorted subarrays A[p..q] and A[q+1,
r].
Working
• As mentioned earlier, Merge Sort uses the Divide and Conquer
Algorithm where a problem is solved by dividing it into numerous
sub-problems, conquering each of the sub-problems individually, and
then combining it to form the end result, just as shown in the picture
below.
Example 1
• Now that we have a fair understanding of what divide and conquer is,
let us try and understand how that is done to sort an array of
integers. Let us consider an array, arr that consists of n unsorted
integers. Our end goal is to sort the array.
• Let us consider an array={38,27,43,3,9,82,10}.
• 1.Divide In this step, we find the midpoint of the given array by using
the formula mid=start+(end-start)/2
• 2. Conquer In this step, we divide the array into subarrays using the
midpoint calculated. We recursively keep dividing the array and keep
calculating the midpoint for doing the same. It is important to note
that a single array element is always sorted. So, our aim is to
continuously divide until all elements in the array are single array
elements. Once that is done, the array elements are combined back
to form a sorted array.
• As mentioned above, our goal is to keep dividing till all elements in
the array are single array elements hence, this is the base case i.e.
when there are n subarrays of the original array that consisted
of n integers. It is now the turn is to sort them and combine them.
• 3. Combine
• Now that all our subarrays are formed, it is now time to combine
them in sorted order.
Example 2
• To know the functioning of merge sort, lets consider an array arr[] =
{38, 27, 43, 3, 9, 82, 10}
• At first, check if the left index of array is less than the right index, if
yes then calculate its mid point
• Now, as we already know that merge sort first divides the whole array
iteratively into equal halves, unless the atomic values are achieved.
• Here, we see that an array of 7 items is divided into two arrays of size
4 and 3 respectively.
• Now, again find that is left index is less than the right index for both
arrays, if found yes, then again calculate mid points for both the
arrays.
• Now, further divide these two arrays into further halves, until the
atomic units of the array is reached and further division is not
possible.
• After dividing the array into smallest units, start merging the elements
again based on comparison of size of elements
• Firstly, compare the element for each list and then combine them into
another list in a sorted manner.
• After the final merging, the list looks like this:
• The following diagram shows the complete merge sort process for an
example array {38, 27, 43, 3, 9, 82, 10}.
• If we take a closer look at the diagram, we can see that the array is
recursively divided into two halves till the size becomes
• Once the size becomes 1, the merge processes come into action and
start merging arrays back till the complete array is merged.
Illustration
Example 3
Example 4
Algorithm
PROCEDURE function mergeSort
FOR each element present in the original array indexed by j
if ( j<= 1 ) return arr

var left = arr[0] to arr[j/2]

var right = arr[j/2+1] to arr[j]

left = mergeSort( left )

right = mergeSort( right )

return merge( left,right )


END FOR
END PROCEDURE
PROCEDURE function mergeSort

WHILE length(left) > 0 and length(right) > 0

if first(left) > first(right)

append first(left) to ans

left = rest(left)

else
append first(right) to ans

right = rest(right)

IF length(left) > 0

insert left in ans


END IF

IF length(right) > 0

insert right in ans


END IF
return result
END PROCEDURE
Understanding the Algorithm
• 1. The Divide Step
a. To divide the array into subarrays, we repeatedly do the following steps:
b. Store starting index as start and ending index as end.
• If start<end:
• Find mid by using the formula: start+(end-start)/2
• Divide the left subarray i.e. index start to index mid
• Divide the right subarray i.e. index mid+1 to end
c. If end<start:
• return, as the entire array is traversed.
• The above points will go in recursion and stop dividing when all elements
become single array elements. The combined step is given below.
Merge Sort in action
• The Combine Step
• To combine the 2 subarrays into one sorted array, we use 3 pointers.
One is for traversing the first subarray, one for traversing the second
subarray and the third one is for traversing the final sorted array. We
do the following steps:
1. If any of the arrays have not been traversed entirely
• Compare the first element of both arrays
• Copy a larger element and put it in the final sorted array
• Move the pointer of the subarray that consisted of the larger element.
2. If any of the arrays have been traversed entirely
• Copy all remaining elements into a sorted array.
Step by Step Merge Function
Since we start combining when we have subarrays of length 1, when
we get 2 subarrays to combine, they will be sorted amongst each other.
It is our job to sort these and put them together in the final sorted
array. We accomplish this by having 3 pointers/references.
• At the beginning of the first subarray
• At the beginning of the second subarray
• At the sorted array
Until we reach the end of either of the subarrays, we keep checking
which element is smaller and putting that in the array.
• Here 1 is smaller, so we push that to the sorted array and then move
the pointer of the subarray that contains 1 as the next number
after 1 might be smaller or larger than 6 but the number after 6 is
definitely larger than 1. We continue as follows:
• Now we see that we have reached the end of the second subarray.
This means that the remaining numbers in the first sub-array are
definitely larger and since they are sorted, we insert them in the final
sorted array as-is.
Flowchart
C code
/* C program for Merge Sort */
#include <stdio.h>
#include <stdlib.h>

// Merges two subarrays of arr[].


// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;

/* create temp arrays */


int L[n1], R[n2];
/* Copy data to temp arrays L[] and R[] */
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];

/* Merge the temp arrays back into arr[l..r]*/


i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
/* Copy the remaining elements of L[], if there
are any */
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}

/* Copy the remaining elements of R[], if there


are any */
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r)
{
if (l < r) {
// Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l + (r - l) / 2;

// Sort first and second halves


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

merge(arr, l, m, r);
}
}
/* UTILITY FUNCTIONS */
/* Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
/* Driver code */
int main()
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);

printf("Given array is \n");


printArray(arr, arr_size);

mergeSort(arr, 0, arr_size - 1);

printf("\nSorted array is \n");


printArray(arr, arr_size);
return 0;
}
Output
QUICK SORT
Introduction
• Like Merge Sort, QuickSort is a Divide and Conquer algorithm. It picks
an element as a pivot and partitions the given array around the
picked pivot. There are many different versions of quickSort that pick
pivot in different ways.
• Always pick the first element as a pivot.
• Always pick the last element as a pivot (implemented below)
• Pick a random element as a pivot.
• Pick median as the pivot.
• The key process in quickSort is a partition(). The target of partitions
is, given an array and an element x of an array as the pivot, put x at its
correct position in a 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.
The Partition Algorithm
• There can be many ways to do partition. The logic is simple, we start
from the leftmost element and keep track of the index of smaller (or
equal to) elements as i. While traversing, if we find a smaller element,
we swap the current element with arr[i]. Otherwise, we ignore the
current element.
Algorithm
Pseudo Code for partition
/* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller
(smaller than pivot) to left of pivot and all greater elements to right of pivot */
partition (arr[], low, high)
{
// pivot (Element to be placed at right position)
pivot = arr[high];
i = (low – 1) // Index of smaller element and indicates the
// right position of pivot found so far
for (j = low; j <= high- 1; j++){
// If current element is smaller than the pivot
if (arr[j] < pivot){
i++; // increment index of smaller element
swap arr[i] and arr[j]
}
}
swap arr[i + 1] and arr[high])
return (i + 1)
}
Illustration
• Consider: arr[] = {10, 80, 30, 90, 40, 50, 70}
• Indexes: 0 1 2 3 4 5 6
• low = 0, high = 6, pivot = arr[h] = 70
• Initialize index of smaller element, i = -1
• Traverse elements from j = low to high-1
• j = 0: Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])
• i=0
• arr[] = {10, 80, 30, 90, 40, 50, 70} // No change as i and j are same
• j = 1: Since arr[j] > pivot, do nothing
• j = 2 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])
•i=1
• arr[] = {10, 30, 80, 90, 40, 50, 70} // We swap 80 and 30
• j = 3 : Since arr[j] > pivot, do nothing // No change in i and arr[]
• j = 4 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])
•i=2
• arr[] = {10, 30, 40, 90, 80, 50, 70} // 80 and 40 Swapped
• j = 5 : Since arr[j] <= pivot, do i++ and swap arr[i] with arr[j]
•i=3
• arr[] = {10, 30, 40, 50, 80, 90, 70} // 90 and 50 Swapped
• We come out of loop because j is now equal to high-1.
• Finally we place pivot at correct position by swapping arr[i+1] and
arr[high] (or pivot)
• arr[] = {10, 30, 40, 50, 70, 90, 80} // 80 and 70 Swapped
• Now 70 is at its correct place. All elements smaller than 70 are before
it and all elements greater than 70 are after it.
• Since quick sort is a recursive function, we call the partition function
again at left and right partitions
• Again call function at right part and swap 80 and 90
Algorithm – Partition
//low and high are the lowest & highest index of the array/subarray respectively
function partition(array, low, high) {

// selecting the rightmost element as pivot


pivot = array[high]

//setting the left pointer to point at the lowest index initially


left = low

//setting the left pointer to point at the lowest index initially


right = high - 1;
//running a loop till left is smaller than right
while(left <= right)

//incrementing the value of left until the value at left'th


//index is smaller than pivot
while(array[left] < pivot)
left = left + 1
end while
//decrementing the value of right until the value at right'th
//index is greater than pivot
while(array[right] > pivot)
right = right - 1
end while

if(left < right)


//swapping the elements at left & right index
swap(array[left], array[right])
end if

end while
// swapping pivot with the element where left and right meet
swap(array[left], array[high])

// return the partition point


return left

end function
Algorithm – Quick Sort Function
quickSort(array, low, high) {
if low < high

// since this function returns the point where the array is


//partitioned, it is used to track the subarrays/partitions in the
// array
pi = partition(array, low, high)
// recursively calling the function on left subarray
quickSort(array, low, pi - 1)

// recursively calling the function on right subarray


quickSort(array, pi + 1, high)

end if

end quicksort function


C code
// function to swap the elements
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// finding the partition point & rearranging the array
int partition(int array[], int low, int high) {
// selecting the rightmost element as pivot
int pivot = array[high];
//setting the left pointer to point at the lowest index initially
int left = low;
//setting the left pointer to point at the lowest index initially
int right = high - 1;
//running a loop till left is smaller than right
while(left <= right){
//incrementing the value of left until the value at left'th index is smaller than pivot
while(array[left] < pivot){
left++;
}
//decrementing the value of right until the value at right'th index is greater than
pivot
while(array[right] > pivot){
right--;
}

if(left < right){


//swapping the elements at left & right index
swap(&array[left], &array[right]);
}
}
// swapping pivot with the element where left and right meet
swap(array[left], array[high]);
// return the partition point
return (left);
}
void quickSort(int array[], int low, int high) {
if (low < high) {

// since this function returns the point where the array is partitioned, it is used to track the
subarrays/partitions in the array
int pi = partition(array, low, high);

// recursively calling the function on left subarray


quickSort(array, low, pi - 1);

// recursively calling the function on right subarray


quickSort(array, pi + 1, high);
}
}
• 1. Where is quick sort used?
• Quick sort is used in separating Nth smallest or the largest element
from an array.
• Being a fast sorting algorithm, quick sort is used by various
departments in information retrieval.
• Quick sort is used for numerical computing where the efficient
algorithms use priority queues and in turn quick sort for achieving
accuracy.
• It is used where fast searching and/or sorting is the priority.
• 2. Is Quick sort a stable algorithm?
• An algorithm is called stable if the relative order of two equal
elements is preserved. Therefore, quick sort is not a stable algorithm
because ordering is done on the basis of the pivot’s position.
• 3. Why Quick sort runs faster than merge sort?
• Quick sort is an in-place algorithm. But in merge sort, a new
temporary array is required to merge the sorted subarrays. Therefore,
quick sort is faster than merge sort.
• Moreover, in quick sort, the worst case can be avoided by randomly
choosing an element as the pivot, and performing sorting around it.
Thus, a properly implemented quick sort has a time complexity
of O(nlogn) in the average case.
• 4. Why Quick sort is preferred for array?
• Quick sort is cache-friendly, which means it does not create
unnecessary buffers in the cache memory and slow the system down.
It is because, when used for arrays, quick sort has a good locality of
reference

You might also like