Heapsort

Heapsort is an $$O(n \log n)$$ sort that is not stable, not adaptive, and uses $$O(1)$$ memory. It is used by fast quicksort algorithms, such as Pattern-Defeating Quicksort and C++'s, as a fallback when there are too many bad partitions.

The heap


A binary heap, or just heap, is a complete binary tree where each node has 2 children, except on the bottom right. Also, each node has to be greater than its children.

Sinking
If a node is smaller than a child, the heap order is violated, which is then swapped with the larger of its children, and the node keeps getting swapped down until it is larger than both its children.

The Sort
The array is first interpreted as a heap with the following scheme: root at index $$0$$, current node at $$i$$, left child at index $$2i + 1$$, right child at index $$2i + 2$$, and parent at $$\lfloor\frac{i - 1}{2}\rfloor$$.

Then, the array is heap-ordered by sink operations.

Finally, the root (it has to be the biggest) is swapped to the end and the heap is re-heapified.

The initial heapify operation is $$O(n)$$, and sorting the heap is $$O(n \log n)$$.

Pseudocode
procedure LeftChild(int i) do return i * 2 + 1 end procedure RightChild(int i) do return i * 2 + 2 end procedure Parent(int i) do return floor((i - 1) / 2) end procedure Sink(array arr,int start,int end) do int root = start while LeftChild(root) <= end do int child = LeftChild(i) int swap = root if RightChild(root) <= end and arr[swap] < RightChild(root) do child = RightChild(root) end if if swap == root do return else swap arr[root] and arr[swap] root = swap end if end while end procedure heapify(array arr,int count) do int start = Parent(count - 1) while start >= 0 do Sink(arr,start,count - 1) start -- end while end procedure heap_sort(array arr) do heapify(arr,length(arr)) int end = length(arr) - 1 while end > 0 do swap arr[end] and arr[0] Sink(arr,0,end) end while end

Complexity
The heapify procedure defined above takes $$O(n)$$ operations. The sink procedure takes $$O(\log n)$$ operations, that is called $$O(n)$$ times during re-heapification. Therefore the algorithm is in $$O(n + n \log n) = O(n \log n)$$ time.