Skip to main content
Binary Trees & Graphs
CHAPTER 15 Beginner

Heap Sort Algorithm

Updated: May 17, 2026
10 min read

# CHAPTER 15

Heap Sort Algorithm

1. Introduction

Throughout computer science, sorting massive arrays is a foundational challenge.
  • Bubble Sort is easy to code but takes a horrific $O(N^2)$ Time.
  • Merge Sort is lightning fast at $O(N \log N)$ Time, but it requires allocating massive backup arrays, bloating Space Complexity to $O(N)$.
Can we achieve the blazing speed of Merge Sort, but sort the data In-Place without consuming a single extra byte of RAM? Yes. By weaponizing the Heapify algorithm from Chapter 14, we can physically mutate a raw, chaotic array into a Max-Heap, and then systematically extract the highest values to sort the array backwards. This is the magnificent Heap Sort.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the Two-Phase architecture of Heap Sort.
  • Execute the $O(N)$ "Build-Heap" phase to restructure chaotic arrays.
  • Execute the $O(N \log N)$ "Extraction" phase to finalize the sorting.
  • Prove the $O(1)$ Space Complexity that makes Heap Sort superior to Merge Sort for embedded systems.

3. Phase 1: Build-Heap (Structuring the Chaos)

You are handed a chaotic Array: [4, 10, 3, 5, 1]. Our first goal is to convert this Array into a valid Max-Heap. We do not create a new array. We morph it in-place.

The Strategy: We run the Heapify Down algorithm (from Chapter 14) on the internal nodes. *Shortcut:* We do NOT need to Heapify the Leaf nodes! (A leaf node has no children, so it is already a perfectly valid 1-node Heap). The leaves occupy exactly the back half of the array. We start at the last non-leaf parent (N/2 - 1) and work backward to Index 0.

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

  1. 1. Last non-leaf node is at index 1 (Value 10).
  1. 2. Heapify 10: Compare with children 5 and 1. It is already $>$ both. OK.
  1. 3. Move backwards to index 0 (Value 4).
  1. 4. Heapify 4: Compare with children 10 and 3. Largest is 10. Swap 4 and 10.
  1. 5. Array becomes [10, 4, 3, 5, 1].
  1. 6. Heapify 4 again (it moved to index 1): Compare with children 5, 1. Swap 4 and 5.
  1. 7. Array becomes [10, 5, 3, 4, 1].
*Phase 1 Complete! The chaotic array is now a valid Max-Heap!*

4. Phase 2: Extraction (The Sorting Engine)

Now we have a Max-Heap: [10, 5, 3, 4, 1]. We know the absolute largest number is sitting at Index 0 (10).

The Strategy:

  1. 1. Swap Root to Back: Swap Index 0 (10) with the absolute last element in the array (1). Array becomes [1, 5, 3, 4, 10].
  1. 2. Lock the Back: The number 10 is now in its final, perfectly sorted position at the end of the array! We mathematically "lock" that array slot and pretend the array is now 1 element smaller.
  1. 3. Heapify Root: The new Root (1) is a weak number. Run Heapify Down on Index 0 to bubble it down and push the *next* largest number up to the Root.
  1. 4. Repeat: Repeat this swapping and locking until the array size shrinks to 1.

Trace Phase 2:

  1. 1. Swap 10 and 1. Array: [1, 5, 3, 4, | 10]. (Locked 10).
  1. 2. Heapify 1. It swaps with 5. Array: [5, 1, 3, 4, | 10].
  1. 3. Heapify 1 again. It swaps with 4. Array: [5, 4, 3, 1, | 10]. (Heap restored).
  1. 4. Swap Root 5 to the back. Array: [1, 4, 3, | 5, 10]. (Locked 5).
  1. 5. Heapify 1. Swaps with 4. Array: [4, 1, 3, | 5, 10].
  1. 6. Swap Root 4 to back. Array: [3, 1, | 4, 5, 10].
  1. 7. Swap Root 3 to back. Array: [1, | 3, 4, 5, 10].
*The Array is perfectly sorted!*

5. Python Code Implementation

Notice how no extra arrays are created. Everything happens via index swapping.
python
12345678910111213141516171819202122232425
def heapify(arr, n, i):
    largest = i
    l = 2 * i + 1
    r = 2 * i + 2

    if l < n and arr[l] > arr[largest]:
        largest = l
    if r < n and arr[r] > arr[largest]:
        largest = r

    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i] # Swap
        heapify(arr, n, largest) # Recurse

def heapSort(arr):
    n = len(arr)

    # Phase 1: Build Max-Heap (start at last non-leaf)
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    # Phase 2: Extract elements one by one
    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i] # Swap Root to back
        heapify(arr, i, 0) # Heapify the reduced array (size i)

6. Complexity Analysis

  • Time Complexity (Build Heap): $O(N)$. (A mathematical optimization proves building a heap bottom-up takes linear time, not $N \log N$).
  • Time Complexity (Extraction): $O(N \log N)$. (We extract $N$ elements, and each Heapify takes $\log N$ time).
  • Total Time Complexity: $O(N \log N)$ Guaranteed Worst-Case.
  • Space Complexity: $O(1)$ Constant Space. The algorithm mutates the original array in-place, making it vastly superior to Merge Sort for low-RAM systems!

7. Common Mistakes

  • Using a Min-Heap for Ascending Order: To sort an array in ascending order (1, 2, 3), you MUST use a Max-Heap. Why? Because you extract the massive Root and throw it to the *back* of the array. If you use a Min-Heap, you put the tiny numbers at the back, resulting in a descending reverse-sorted array!

8. Exercises

  1. 1. Execute Phase 1 (Build Max-Heap) manually on the array [2, 8, 5, 3, 9, 1]. Show the final state of the array before Phase 2 begins.
  1. 2. In Phase 1, why is it mathematically redundant to call the Heapify function on indices greater than (N/2 - 1)?

9. MCQs with Answers

Question 1

What specific sequence of architectural phases defines the complete Heap Sort algorithm?

Question 2

When initiating Phase 1 (Build-Heap), why does the optimization loop mathematically bypass the absolute back half of the array matrix?

Question 3

If a software architect demands the finalized array sequence be printed in perfect Ascending Order (e.g., 1, 2, 3, 4), which specific geometric Heap structure must be synthesized during Phase 1?

Question 4

During Phase 2 (Extraction), after the massive Root variable is successfully swapped to the terminal locked coordinate, what specific algorithmic action must immediately follow?

Question 5

What represents the absolute worst-case Time Complexity ceiling for the holistic execution of a complete Heap Sort upon a chaotic, unorganized array?

Question 6

When directly evaluating architectural Space Constraints, what catastrophic limitation forces embedded systems engineers to deploy Heap Sort over the equally fast Merge Sort?

Question 7

What specific vulnerability prevents Heap Sort from being categorized as a "Stable" sorting algorithm?

Question 8

If Phase 1 (Build-Heap) executes, what is its mathematical Time Complexity?

Question 9

When executing the Phase 2 Extraction loop, why does the loop parameter n artificially decrease by 1 upon every single iteration cycle?

Q10. True or False: Because QuickSort has a superior theoretical average-case performance, Heap Sort is mathematically obsolete and never deployed in modern Operating Systems. a) True. QuickSort entirely replaced Heap Sort in the 1990s. b) False. QuickSort suffers from an apocalyptic worst-case degradation to $O(N^2)$ when fed maliciously structured data. Advanced sorting libraries (like C++ std::sort) execute "IntroSort"—deploying QuickSort initially, but immediately hard-switching to Heap Sort if catastrophic recursion limits are breached, guaranteeing a flawless $O(N \log N)$ failsafe! Answer: b) False. QuickSort suffers from an apocalyptic worst-case degradation to $O(N^2)$...

11. Interview Preparation

Top Interview Questions:
  • *Algorithm Selection:* "You are programming the guidance computer for an interplanetary satellite. Memory RAM is extremely limited, and missing a processing deadline will crash the ship. Do you use QuickSort, Merge Sort, or Heap Sort?" *(Answer: Heap Sort! Merge Sort wastes too much RAM ($O(N)$ Space). QuickSort risks a catastrophic $O(N^2)$ Worst-Case time delay. Only Heap Sort guarantees blazing $O(N \log N)$ speed combined with zero RAM overhead ($O(1)$ Space). It is the ultimate bulletproof embedded algorithm!)*

12. Summary

Heap Sort is a masterpiece of geometric array manipulation. By realizing that a standard 1D Array hides a 2D Complete Binary Tree within its index mathematics, engineers can run aggressive vertical Heapify rotations to crush chaotic data into order. It achieves the holy grail of sorting: $O(N \log N)$ speed with absolute zero external RAM consumption.

13. Next Chapter Recommendation

We have spent chapters extracting numbers from arrays and comparing integers. What happens when the data isn't a number, but massive strings of English text? How does Google Autocomplete predict your search instantly out of billions of words? In Chapter 16: Trie Data Structure, we leave the Binary world and build Prefix Trees designed explicitly for character string domination.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·