Skip to content
intermediatePhase 3 · Sorting & Searching

Heap Sort

Understand heap-based sorting and priority queue applications.

1h
4 problems
Topic Progress0%

Binary Heap Fundamentals

A binary heap is a complete binary tree that satisfies the heap property. It's commonly implemented as an array.

Heap Property

  • Max-Heap: Parent ≥ children (largest at root)
  • Min-Heap: Parent ≤ children (smallest at root)

Array Representation

Max-Heap:        10
               /    \
              7      8
             / \\    / \
            5   6  3   4

Array: [10, 7, 8, 5, 6, 3, 4]

Index relationships (0-based):
- Parent of i: (i-1)/2
- Left child of i: 2*i + 1
- Right child of i: 2*i + 2

Java Heap Implementation

public class MaxHeap {
    private int[] heap;
    private int size;
    
    public MaxHeap(int capacity) {
        heap = new int[capacity];
        size = 0;
    }
    
    private int parent(int i) { return (i - 1) / 2; }
    private int leftChild(int i) { return 2 * i + 1; }
    private int rightChild(int i) { return 2 * i + 2; }
    
    private void swap(int i, int j) {
        int temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
}

Heapify (Sift Down)

private void heapify(int i) {
    int largest = i;
    int left = leftChild(i);
    int right = rightChild(i);
    
    if (left < size && heap[left] > heap[largest]) {
        largest = left;
    }
    
    if (right < size && heap[right] > heap[largest]) {
        largest = right;
    }
    
    if (largest != i) {
        swap(i, largest);
        heapify(largest);  // Recursively heapify affected subtree
    }
}

Insert Operation

public void insert(int value) {
    if (size == heap.length) {
        throw new RuntimeException("Heap is full");
    }
    
    // Place at end and sift up
    heap[size] = value;
    size++;
    siftUp(size - 1);
}

private void siftUp(int i) {
    while (i > 0 && heap[parent(i)] < heap[i]) {
        swap(parent(i), i);
        i = parent(i);
    }
}

Extract Max/Min

public int extractMax() {
    if (size == 0) {
        throw new RuntimeException("Heap is empty");
    }
    
    int max = heap[0];
    heap[0] = heap[size - 1];
    size--;
    heapify(0);
    
    return max;
}

Build Heap from Array

public void buildHeap(int[] arr) {
    heap = arr;
    size = arr.length;
    
    // Start from last non-leaf node
    for (int i = size / 2 - 1; i >= 0; i--) {
        heapify(i);
    }
}

Complexity

Operation Time
Insert O(log n)
Extract O(log n)
Peek O(1)
Build Heap O(n)

Heap Sort Algorithm

Heap sort uses a max-heap to sort in ascending order:

  1. Build max-heap from array
  2. Extract max repeatedly, placing at end

Algorithm Steps

  1. Build max-heap (largest element at root)
  2. Swap root (max) with last element
  3. Reduce heap size by 1
  4. Heapify root to maintain heap property
  5. Repeat until heap size is 1

Visual Example

Original: [4, 10, 3, 5, 1]

Build Max-Heap: [10, 5, 3, 4, 1]

Iteration 1:
Swap 10 and 1: [1, 5, 3, 4, 10]
Heapify: [5, 4, 3, 1, 10]

Iteration 2:
Swap 5 and 1: [1, 4, 3, 5, 10]
Heapify: [4, 1, 3, 5, 10]

Iteration 3:
Swap 4 and 3: [3, 1, 4, 5, 10]
Heapify: [3, 1, 4, 5, 10]

Iteration 4:
Swap 3 and 1: [1, 3, 4, 5, 10]
Heapify: [1, 3, 4, 5, 10]

Sorted: [1, 3, 4, 5, 10]

Java Implementation

public void heapSort(int[] arr) {
    int n = arr.length;
    
    // Build max-heap
    for (int i = n / 2 - 1; i >= 0; i--) {
        heapify(arr, n, i);
    }
    
    // Extract elements one by one
    for (int i = n - 1; i > 0; i--) {
        // Move current root to end
        swap(arr, 0, i);
        
        // Heapify reduced heap
        heapify(arr, i, 0);
    }
}

private void heapify(int[] arr, int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    
    if (left < n && arr[left] > arr[largest]) {
        largest = left;
    }
    
    if (right < n && arr[right] > arr[largest]) {
        largest = right;
    }
    
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, n, largest);
    }
}

private void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

Complexity Analysis

Aspect Complexity
Time (all cases) O(n log n)
Space O(1) - in-place
Stable No

Heap Sort vs Other Sorts

Algorithm Time Space Stable In-place
Heap Sort O(n log n) O(1) No Yes
Merge Sort O(n log n) O(n) Yes No
Quick Sort O(n log n) avg O(log n) No Yes

When to Use Heap Sort

Use when:

  • Guaranteed O(n log n) needed
  • O(1) space required
  • Priority queue operations needed
  • Online sorting (elements arrive one by one)

Avoid when:

  • Stability required (use merge sort)
  • Cache performance important (quicksort better)
  • Nearly sorted data (insertion sort better)

Interactive Visualization

Heap Sort Visualization

Press Play or Step to begin
CurrentFound / DoneEliminatedUnvisited

Practice Problems

0/1solved
Kth Largest Element in an Array
Heap

Given an integer array nums and an integer k, return the kth largest element in the array. Note: it is the kth largest element in sorted order, not the kth distinct element.

Example:

Input: nums = [3,2,1,5,6,4], k = 2

Output: 5

The 2nd largest element is 5 (sorted: [1,2,3,4,5,6]).

Optimal Solution — O(n log k) for min-heap approach time, O(k) for min-heap space

Use min-heap of size k. First k elements build heap, then for each remaining element, if larger than heap root, replace and heapify.

class Solution {
    public int findKthLargest(int[] nums, int k) {
        // Min-heap of size k
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        
        for (int num : nums) {
            minHeap.offer(num);
            if (minHeap.size() > k) {
                minHeap.poll();  // Remove smallest
            }
        }
        
        return minHeap.peek();  // Root is kth largest
    }
}

// Alternative: Using heap sort approach
public int findKthLargestHeapSort(int[] nums, int k) {
    // Build max-heap
    for (int i = nums.length / 2 - 1; i >= 0; i--) {
        heapify(nums, nums.length, i);
    }
    
    // Extract k-1 largest elements
    for (int i = 0; i < k - 1; i++) {
        swap(nums, 0, nums.length - 1 - i);
        heapify(nums, nums.length - 1 - i, 0);
    }
    
    return nums[0];
}

private void heapify(int[] arr, int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    
    if (left < n && arr[left] > arr[largest]) largest = left;
    if (right < n && arr[right] > arr[largest]) largest = right;
    
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, n, largest);
    }
}

private void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

Edge Cases:

  • k equals array length
  • k equals 1 (return maximum)
  • All elements same
  • Negative numbers
  • Single element array

Quiz

1. What is the time complexity of heap sort?

Question 1 options

2. Why is heap sort not stable?

Question 2 options

3. What is the primary purpose of Heap Sort?

Question 3 options

4. What is a common mistake when implementing Heap Sort?

Question 4 options

Flashcards

Question

What is the space complexity of heap sort?

Answer

O(1) - it sorts in-place using the array itself as the heap.

Question

How do you find parent/child indices in a binary heap array?

Answer

Parent of i: (i-1)/2, Left child: 2*i+1, Right child: 2*i+2 (0-indexed).

Question

What is Heap Sort?

Answer

Heap Sort is a key concept in software engineering.

Question

When to use Heap Sort?

Answer

Use Heap Sort when building production systems that require reliability, scalability, and maintainability.

Question

Heap Sort best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1.Heap sort provides O(n log n) with O(1) space
  • 2.Building heap is O(n), not O(n log n)
  • 3.Heap sort is not stable but is in-place
  • 4.Priority queues are implemented using heaps

Interview Tips

  • Explain the difference between max-heap and min-heap
  • Know the formulas for parent/child index calculations
  • Discuss when to use heap sort vs other O(n log n) sorts
  • Mention heap's role in priority queue and top-k problems

Cheat Sheet

Heap Sort Cheat Sheet

Algorithm:

  1. Build max-heap from array
  2. Swap root with last element
  3. Heapify root
  4. Repeat until sorted

Heapify (Max-Heap):

void heapify(int[] arr, int n, int i) {
    int largest = i;
    int left = 2*i+1, right = 2*i+2;
    if (left < n && arr[left] > arr[largest]) largest = left;
    if (right < n && arr[right] > arr[largest]) largest = right;
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, n, largest);
    }
}

Complexity:

  • Time: O(n log n) all cases
  • Space: O(1) in-place
  • Stable: No

Key Formulas (0-indexed):

  • Parent: (i-1)/2
  • Left child: 2*i+1
  • Right child: 2*i+2