Ternary heapsort replaces the binary heap with a ternary heap, where each node has up to three children instead of two. This reduces the height of the heap, which can reduce the number of levels traversed during heap operations.
The tradeoff is that each step may require more comparisons to select the largest child.
Problem
Given an array of length , reorder it such that:
Idea
In a ternary heap, the children of node are:
This reduces the height of the heap to:
which is smaller than the binary heap height:
Algorithm
ternary_heapsort(A):
build_ternary_heap(A)
for i from n - 1 down to 1:
swap A[0] and A[i]
heapify(A, 0, i)Heap construction:
build_ternary_heap(A):
for i from floor((n - 2) / 3) down to 0:
heapify(A, i, n)Heapify:
heapify(A, i, size):
largest = i
c1 = 3*i + 1
c2 = 3*i + 2
c3 = 3*i + 3
if c1 < size and A[c1] > A[largest]:
largest = c1
if c2 < size and A[c2] > A[largest]:
largest = c2
if c3 < size and A[c3] > A[largest]:
largest = c3
if largest != i:
swap A[i] and A[largest]
heapify(A, largest, size)Example
Let:
Construct a ternary heap:
Then repeatedly extract the maximum and restore the heap until sorted.
Correctness
The heap property ensures that every parent node is greater than or equal to its children. The root is therefore the maximum element. Swapping it with the last element places it in its correct position. Repeating this process produces a sorted array.
Complexity
| metric | value |
|---|---|
| build heap | |
| extraction |
Height:
Each heapify step examines up to three children, so comparisons per level increase slightly.
Total complexity remains:
Properties
| property | value |
|---|---|
| stable | no |
| in-place | yes |
| branching factor | 3 |
| height | lower than binary heap |
| comparisons per level | higher |
Notes
Ternary heapsort trades fewer levels for more comparisons at each level. In practice, performance depends on hardware and data patterns. Binary heaps are more common, but higher arity heaps can perform better in some environments.
This idea generalizes to -ary heaps, where each node has children.
Implementation
def ternary_heapsort(a):
n = len(a)
def heapify(i, size):
largest = i
c1 = 3 * i + 1
c2 = 3 * i + 2
c3 = 3 * i + 3
if c1 < size and a[c1] > a[largest]:
largest = c1
if c2 < size and a[c2] > a[largest]:
largest = c2
if c3 < size and a[c3] > a[largest]:
largest = c3
if largest != i:
a[i], a[largest] = a[largest], a[i]
heapify(largest, size)
for i in range((n - 2) // 3, -1, -1):
heapify(i, n)
for i in range(n - 1, 0, -1):
a[0], a[i] = a[i], a[0]
heapify(0, i)
return afunc TernaryHeapSort(a []int) {
n := len(a)
var heapify func(int, int)
heapify = func(i, size int) {
largest := i
c1 := 3*i + 1
c2 := 3*i + 2
c3 := 3*i + 3
if c1 < size && a[c1] > a[largest] {
largest = c1
}
if c2 < size && a[c2] > a[largest] {
largest = c2
}
if c3 < size && a[c3] > a[largest] {
largest = c3
}
if largest != i {
a[i], a[largest] = a[largest], a[i]
heapify(largest, size)
}
}
for i := (n - 2) / 3; i >= 0; i-- {
heapify(i, n)
}
for i := n - 1; i > 0; i-- {
a[0], a[i] = a[i], a[0]
heapify(0, i)
}
}