1. Quick sort
Quick sort is a highly efficient sorting algorithm and is based on partitioning
of array of data into smaller arrays. A large array is partitioned into two arrays
one of which holds values smaller than specified value say pivot based on
which the partition is made and another array holds values greater than pivot
value.
The quick sort partitions an array and then calls itself recursively twice to sort
the resulting two subarray. This algorithm is quite efficient for large sized
data sets as its average and worst case complexity are of O(nlogn) where n
are no. of items.
Partition in Quicksort
The below given animated representation explains how to find pivot value in
the array.
The pivot value divides the list in to two parts. And recursively we find pivot
for each sub-lists until all lists contains only one element.
QuickSort Pivot Algorithm
Based on our understanding of partitioning in quicksort, we should now try
to write an algorithm for it here.
Step 1 − Choose the highest index value has pivot
Step 2 − Take two variables to point left and right of the list excluding pivot
Step 3 − left points to the low index
Step 4 − right points to the high
2. Step 5 − while value at left is less than pivot move right
Step 6 − while value at right is greater than pivot move left
Step 7 − if both step 5 and step 6 does not match swap left and right
Step 8 − if left ≥ right, the point where they met is new pivot
QuickSort Pivot Pseudocode
The pseudocode for the above algorithm can be derived as −
function partitionFunc(left, right, pivot)
leftPointer = left -1
rightPointer = right
while True do
while A[++leftPointer] < pivot do
//do-nothing
end while
while rightPointer > 0 && A[--rightPointer] > pivot do
//do-nothing
end while
if leftPointer >= rightPointer
break
else
swap leftPointer,rightPointer
end if
end while
swap leftPointer,right
return leftPointer
end function
3. QuickSort Algorithm
Using pivot algorithm recursively we end-up with smaller possible partitions.
Each partition then processed for quick sort. We define recursive algorithm
for quicksort as below −
Step 1 − Make the right-most index value pivot
Step 2 − partition the array using pivot value
Step 3 − quicksort left partition recursively
Step 4 − quicksort right partition recursively
Quick sort is a highly efficient sorting algorithm and is based on partitioning
of array of data into smaller arrays. A large array is partitioned into two arrays
one of which holds values smaller than specified value say pivot based on
which the partition is made and another array holds values greater than pivot
value.
Implementation in C
#include <stdio.h>
#include <stdbool.h>
#define MAX 7
int intArray[MAX] = {4,6,3,2,1,9,7};
void printline(int count){
int i;
for(i = 0;i <count-1;i++){
printf("=");
}
printf("=n");
}
4. void display(){
int i;
printf("[");
// navigate through all items
for(i = 0;i<MAX;i++){
printf("%d ",intArray[i]);
}
printf("]n");
}
void swap(int num1, int num2){
int temp = intArray[num1];
intArray[num1] = intArray[num2];
intArray[num2] = temp;
}
int partition(int left, int right, int pivot){
int leftPointer = left -1;
int rightPointer = right;
while(true){
while(intArray[++leftPointer] < pivot){
//do nothing
}
while(rightPointer > 0 && intArray[--rightPointer] > pivot){
//do nothing
}
6. printline(50);
quickSort(0,MAX-1);
printf("Output Array: ");
display();
printline(50);
}
If we compile and run the above program then it would produce following
result −
Output
Input Array: [4 6 3 2 1 9 7 ]
==================================================
pivot swapped :9,7
Updated Array: [4 6 3 2 1 7 9 ]
pivot swapped :4,1
Updated Array: [1 6 3 2 4 7 9 ]
item swapped :6,2
pivot swapped :6,4
Updated Array: [1 2 3 4 6 7 9 ]
pivot swapped :3,3
Updated Array: [1 2 3 4 6 7 9 ]
Output Array: [1 2 3 4 6 7 9 ]
==================================================
Merge sort is a sorting technique based on divide and conquer technique.
With worst-case time complexity being Ο(n log n), it is one of the most
respected algorithms.
Merge sort first divides the array into equal halves and then combines them
in a sorted manner.
How merge sort works
To understand merge sort, we take an unsorted array as depicted below −
7. We know that merge sort first divides the whole array iteratively into equal
halves unless the atomic values are achieved. We see here that an array of
8 items is divided into two arrays of size 4.
This does not change the sequence of appearance of items in the original.
Now we divide these two arrays into halves.
We further divide these arrays and we achieve atomic value which can no
more be divided.
Now, we combine them in exactly same manner they were broken down.
Please note the color codes given to these lists.
We first compare the element for each list and then combine them into
another list in sorted manner. We see that 14 and 33 are in sorted positions.
We compare 27 and 10 and in the target list of 2 values we put 10 first,
followed by 27. We change the order 19 and 35. 42 and 44 are placed
sequentially.
In next iteration of combining phase, we compare lists of two data values,
and merge them into a list of foud data values placing all in sorted order.
8. After final merging, the list should look like this −
Now we should learn some programming aspects of merge sorting.
Algorithm
Merge sort keeps on dividing the list into equal halves until it can no more be
divided. By definition, if it is only one element in the list, it is sorted. Then
merge sort combines smaller sorted lists keeping the new list sorted too.
Step 1 − if it is only one element in the list it is already sorted, return.
Step 2 − divide the list recursively into two halves until it can no more be divided.
Step 3 − merge the smaller lists into new list in sorted order.
Merge sort is a sorting technique based on divide and conquer technique.
With worst-case time complexity being Ο(n log n), it is one of the most
respected algorithms
Implementation in C
We shall see the implementation of merge sort in c programming language
here −
#include <stdio.h>
#define max 10
int a[10] = { 10, 14, 19, 26, 27, 31, 33, 35, 42, 44 };
int b[10];
void merging(int low, int mid, int high) {
int l1, l2, i;
for(l1 = low, l2 = mid + 1, i = low; l1 <= mid && l2 <= high; i++) {
10. printf("List before sortingn");
for(i = 0; i <= max; i++)
printf("%d ", a[i]);
sort(0, max);
printf("nList after sortingn");
for(i = 0; i <= max; i++)
printf("%d ", a[i]);
}
Output
The output of the program should be as follows −
List before sorting
10 14 19 26 27 31 33 35 42 44 0
List after sorting
0 10 14 19 26 27 31 33 35 42 44
Heap Sort
Heap sort is a comparison based sorting technique based on Binary Heap data structure. It is
similar to selection sort where we first find the maximum element and place the maximum
element at the end. We repeat the same process for remaining element.
What is Binary Heap?
Let us first define a Complete Binary Tree. A complete binary tree is a binary tree in which every
level, except possibly the last, is completely filled, and all nodes are as far left as possible
(Source Wikipedia)
A Binary Heap is a Complete Binary Tree where items are stored in a special order such that
value in a parent node is greater(or smaller) than the values in its two children nodes. The
former is called as max heap and the latter is called min heap. The heap can be represented by
binary tree or array.
Why array based representation for Binary Heap?
Since a Binary Heap is a Complete Binary Tree, it can be easily represented as array and array
based representation is space efficient. If the parent node is stored at index I, the left child can
be calculated by 2 * I + 1 and right child by 2 * I + 2.
11. Heap Sort Algorithm for sorting in increasing order:
1. Build a max heap from the input data.
2. At this point, the largest item is stored at the root of the heap. Replace it with the last item of
the heap followed by reducing the size of heap by 1. Finally, heapify the root of tree.
3. Repeat above steps until size of heap is greater than 1.
How to build the heap?
Heapify procedure can be applied to a node only if its children nodes are heapified. So the
heapification must be performed in the bottom up order.
Lets understand with the help of an example:
Input data: 4, 10, 3, 5, 1
4(0)
/
10(1) 3(2)
/
5(3) 1(4)
The numbers in bracket represent the indices in the array
representation of data.
Applying heapify procedure to index 1:
4(0)
/
10(1) 3(2)
/
5(3) 1(4)
Applying heapify procedure to index 0:
10(0)
/
5(1) 3(2)
/
4(3) 1(4)
The heapify procedure calls itself recursively to build heap
in top down manner.
//Heap Sort
#include<stdio.h>
12. // To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
void swap(int *num1, int *num2){
int temp = *num1;
*num1 = *num2;
*num2 = temp;
}
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2*i + 1; // left = 2*i + 1
int r = 2*i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i)
{
swap(&arr[i], &arr[largest]);
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
// main function to do heap sort
void heapSort(int arr[], int n)
{ int i;
// Build heap (rearrange array)
for (i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (i=n-1; i>=0; i--)
{
// Move current root to end
13. swap(&arr[0], &arr[i]);
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
/* A utility function to print array of size n */
void printArray(int arr[], int n)
{ int i;
for (i=0; i<n; ++i)
printf("%d ", arr[i] );
}
// Driver program
int main()
{
int arr[] = {4, 10, 3, 5, 1};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
printf("Sorted array is -> ");
printArray(arr, n);
getch();
}
Run on IDE
Output:
Sorted array is -> 1 3 4 5 10
Notes:
Heap sort is an in-place algorithm.
Its typical implementation is not stable, but can be made stable
Time Complexity: Time complexity of heapify is O(Logn). Time complexity of
createAndBuildHeap() is O(n) and overall time complexity of Heap Sort is O(nLogn).
Applications of HeapSort
1. Sort a nearly sorted (or K sorted) array
2. k largest(or smallest) elements in an array
Heap sort algorithm has limited uses because Quicksort and Mergesort are better in practice.
Nevertheless, the Heap data structure itself is enormously used. See Applications of Heap Data
Structure