To implement heapsort in-place using an array-based max-heap, we:1) Build the max-heap in O(n) by calling heapify (siftDown) from the last parent down to index 0.2) Repeatedly swap the root (max) with the last element, reduce heap size, and siftDown the new root. This sorts ascending in-place with O(1) auxiliary memory.java
public class HeapSort {
// Heapsort entry
public static void heapSort(int[] a) {
if (a == null || a.length < 2) return;
int n = a.length;
// Build max-heap in O(n)
for (int i = parent(n - 1); i >= 0; i--) siftDown(a, i, n);
// Extract max and restore heap
for (int end = n - 1; end > 0; end--) {
swap(a, 0, end); // move max to its final position
siftDown(a, 0, end); // sift down in reduced heap
}
}
private static int parent(int i) { return (i - 1) / 2; }
// Sift down element at i within heap size 'n'
private static void siftDown(int[] a, int i, int n) {
while (true) {
int left = 2 * i + 1;
if (left >= n) break;
int right = left + 1;
int largest = (right < n && a[right] > a[left]) ? right : left;
if (a[largest] <= a[i]) break;
swap(a, i, largest);
i = largest;
}
}
private static void swap(int[] a, int i, int j) {
int t = a[i]; a[i] = a[j]; a[j] = t;
}
// Demo
public static void main(String[] args) {
int[] arr = {5, 3, 8, 4, 1, 9, 2};
heapSort(arr);
// arr -> [1,2,3,4,5,8,9]
for (int x : arr) System.out.print(x + " ");
}
}
Why build-heap is O(n): siftDown cost depends on node depth. There are roughly n/2^h nodes at height h, each costing O(h). Summing h * (n/2^h) over h yields O(n) (geometric series), so bottom-up heapify is linear. Overall time: O(n log n) (O(n) build + O(n log n) extraction). Space: O(1) auxiliary. Edge cases: null/empty array, duplicates — all handled.