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:
- Build max-heap from array
- Extract max repeatedly, placing at end
Algorithm Steps
- Build max-heap (largest element at root)
- Swap root (max) with last element
- Reduce heap size by 1
- Heapify root to maintain heap property
- 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
Practice Problems
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?
2. Why is heap sort not stable?
3. What is the primary purpose of Heap Sort?
4. What is a common mistake when implementing Heap Sort?
Flashcards
Question
What is the space complexity of heap sort?
Click to reveal answer
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?
Click to reveal answer
Answer
Parent of i: (i-1)/2, Left child: 2*i+1, Right child: 2*i+2 (0-indexed).
Question
What is Heap Sort?
Click to reveal answer
Answer
Heap Sort is a key concept in software engineering.
Question
When to use Heap Sort?
Click to reveal answer
Answer
Use Heap Sort when building production systems that require reliability, scalability, and maintainability.
Question
Heap Sort best practices
Click to reveal answer
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:
- Build max-heap from array
- Swap root with last element
- Heapify root
- 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