Heap Sort PDF
Heap Sort PDF
In this tutorial, you will learn about the heap sort algorithm and its implementation in
Python, Java, C, and C++.
76, 34, 23, 32] and after sorting, we get a sorted array [3,10,23,32,34,76] .
Heap sort works by visualizing the elements of the array as a special kind of
complete binary tree called a heap.
If the index of any element in the array is i , the element in the index 2i+1 will
become the left child and element in 2i+2 index will become the right child.
Also, the parent of any element at index i is given by the lower bound of (i-
1)/2 .
Relationship between array and heap indices
Let's test it out,
= element in 1 index
= 12
Right child of 1
= element in 2 index
= 9
Similarly,
= element in 3 index
= 5
Right child of 12
= element in 4 index
= 6
Let us also confirm that the rules hold for finding parent of any node
Parent of 9 (position 2)
= (2-1)/2
= ½
= 0.5
~ 0 index
= 1
Parent of 12 (position 1)
= (1-1)/2
= 0 index
= 1
heapify(array)
Root = array[0]
Largest = largest( array[0] , array [2*0 + 1]. array[2*0+2])
if(Root != Largest)
Swap(Root, Largest)
Now let's think of another scenario in which there is more than one level.
To maintain the max-heap property for the entire tree, we will have to keep
pushing 2 downwards until it reaches its correct position.
How to heapify
root element when its subtrees are max-heaps
Thus, to maintain the max-heap property in a tree where both sub-trees are
max-heaps, we need to run heapify on the root element repeatedly until it is
larger than its children or it becomes a leaf node.
This function works for both the base case and for a tree of any size. We can
thus move the root element to the correct position to maintain the max-heap
status for any tree size as long as the sub-trees are max-heaps.
Build max-heap
To build a max-heap from any tree, we can thus start heapifying each sub-tree
from the bottom up and end up with a max-heap after the function is applied to
all the elements including the root element.
In the case of a complete tree, the first index of a non-leaf node is given
by n/2 - 1 . All other nodes after that are leaf-nodes and thus don't need to be
heapified.
So, we can build a maximum heap as
2. Swap: Remove the root element and put at the end of the array (nth position)
Put the last item of the tree (heap) at the vacant place.
3. Remove: Reduce the size of the heap by 1.
4. Heapify: Heapify the root element again so that we have the highest element
at root.
5. The process is repeated until all the items of the list are sorted.
Swap, Remove, and Heapify
The code below shows the operation.
// Heap sort
for (int i = n - 1; i >= 0; i--) {
swap(&arr[0], &arr[i]);
#include <stdio.h>
// Heap sort
for (int i = n - 1; i >= 0; i--) {
swap(&arr[0], &arr[i]);
// Print an array
void printArray(int arr[], int n) {
for (int i = 0; i < n; ++i)
printf("%d ", arr[i]);
printf("\n");
}
// Driver code
int main() {
int arr[] = {1, 12, 9, 5, 6, 10};
int n = sizeof(arr) / sizeof(arr[0]);
heapSort(arr, n);
Best O(nlog n)
Worst O(nlog n)
Average O(nlog n)
Stability No
Heap Sort has O(nlog n) time complexities for all the cases ( best case,
average case, and worst case).
Let us understand the reason why. The height of a complete binary tree
containing n elements is log n
In the worst case scenario, we will need to move an element from the root to
the leaf node making a multiple of log(n) comparisons and swaps.
During the build_max_heap stage, we do that for n/2 elements so the worst
case complexity of the build_heap step is n/2*log n ~ nlog n .
During the sorting step, we exchange the root element with the last element
and heapify the root element. For each element, this again takes log n worst
time because we might have to bring the element all the way from the root to
the leaf. Since we repeat this n times, the heap_sort step is also nlog n .
Also since the build_max_heap and heap_sort steps are executed one after
another, the algorithmic complexity is not multiplied and it remains in the order
of nlog n .
Also it performs sorting in O(1) space complexity. Compared with Quick Sort, it
has a better worst case ( O(nlog n) ) . Quick Sort has complexity O(n^2) for
worst case. But in other cases, Quick Sort is fast. Introsort is an alternative to
heapsort that combines quicksort and heapsort to retain advantages of both:
worst case speed of heapsort and average speed of quicksort.