Mastering Heap Sort: Algorithm, Implementation, and Applications in C

Discover the fundamentals of Heap Sort, a powerful sorting algorithm. Learn its logic, implementation in C, and real-world applications.

Mastering Heap Sort: Algorithm, Implementation, and Applications in C
Photo by Markus Spiske / Unsplash

Introduction

In the realm of computer science, sorting algorithms play a pivotal role in organizing data efficiently. Among the various sorting techniques, Heap Sort stands out due to its efficiency and systematic approach. This blog aims to provide an in-depth understanding of Heap Sort, covering its algorithmic details, implementation in C, and its time and space complexities. By the end of this blog, you will have a comprehensive grasp of Heap Sort and its practical applications.

Algorithm Details

Heap Sort is a comparison-based sorting algorithm that uses a binary heap data structure. It can be divided into two main phases: building a max heap and repeatedly extracting the maximum element from the heap to build the sorted array.

Step-by-Step Logic

  1. Build a Max Heap: Convert the input array into a max heap, where the largest element is at the root.
  2. Extract Elements: Swap the root element with the last element of the heap, reduce the heap size, and heapify the root element.
  3. Repeat: Continue the extraction process until the heap is empty.

Pseudo Code

HeapSort(arr):
    n = length(arr)
    
    # Build Max Heap
    for i = n // 2 - 1 to 0:
        MaxHeapify(arr, n, i)
    
    # Extract elements from heap
    for i = n - 1 to 0:
        swap(arr[0], arr[i])
        MaxHeapify(arr, i, 0)

MaxHeapify(arr, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    if left < n and arr[left] > arr[largest]:
        largest = left

    if right < n and arr[right] > arr[largest]:
        largest = right

    if largest != i:
        swap(arr[i], arr[largest])
        MaxHeapify(arr, n, largest)

Explanation of Pseudo Code

  1. HeapSort(arr):
    • We first build a max heap from the array. This is done by calling the MaxHeapify function starting from the last non-leaf node to the root.
    • Once the max heap is built, we repeatedly swap the root of the heap with the last element and reduce the heap size. We then call MaxHeapify to maintain the heap property.
  2. MaxHeapify(arr, n, i):
    • This function ensures the max heap property for a subtree rooted at index i, given that the subtrees are already heaps.
    • It compares the root with its left and right children and swaps it with the largest if necessary. This process is recursively applied until the heap property is restored.

Implementation in C

Let's translate the above logic into a C program.

#include <stdio.h>

// Function to swap two elements
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// Function to heapify a subtree rooted with node i
void MaxHeapify(int arr[], int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    // If left child is larger than root
    if (left < n && arr[left] > arr[largest])
        largest = left;

    // If right child is larger than largest so far
    if (right < n && arr[right] > arr[largest])
        largest = right;

    // If largest is not root
    if (largest != i) {
        swap(&arr[i], &arr[largest]);
        // Recursively heapify the affected sub-tree
        MaxHeapify(arr, n, largest);
    }
}

// Main function to do heap sort
void HeapSort(int arr[], int n) {
    // Build heap (rearrange array)
    for (int i = n / 2 - 1; i >= 0; i--)
        MaxHeapify(arr, n, i);

    // One by one extract an element from heap
    for (int i = n - 1; i > 0; i--) {
        // Move current root to end
        swap(&arr[0], &arr[i]);

        // Call max heapify on the reduced heap
        MaxHeapify(arr, i, 0);
    }
}

// Utility function to print array
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

// Driver program
int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);

    HeapSort(arr, n);

    printf("Sorted array is \n");
    printArray(arr, n);
    return 0;
}

Explanation of C Code

  1. swap(int *a, int *b):
    • A helper function to swap two integers using pointers.
  2. MaxHeapify(int arr[], int n, int i):
    • Similar to the pseudo code, this function maintains the max heap property for the subtree rooted at index i.
  3. HeapSort(int arr[], int n):
    • Builds a max heap from the input array.
    • Repeatedly extracts the maximum element from the heap and calls MaxHeapify to maintain the heap structure.
  4. printArray(int arr[], int n):
    • Utility function to print the elements of an array.
  5. main():
    • The driver function to test the heap sort implementation.

Time and Space Complexity

Understanding the complexity of Heap Sort is crucial for evaluating its performance.

Time Complexity

  • Building the Max Heap: O(n). This is because MaxHeapify is called n/2 times and each call takes O(log n) time.
  • Heap Sort Process: O(n log n). This involves extracting the maximum element n times, each extraction taking O(log n) time.
  • Total Time Complexity: O(n log n).

Space Complexity

  • Heap Sort is an in-place sorting algorithm. It does not require any extra space for sorting; hence the space complexity is O(1).

Usage of Heap Sort

Heap Sort is particularly useful in scenarios where a stable and reliable sorting algorithm is required with consistent performance. Some common applications include:

  • Priority Queues: Heap Sort forms the basis of priority queue implementations.
  • Real-Time Systems: Where predictable performance is crucial.
  • Heaps in Graph Algorithms: Such as Dijkstra's shortest path algorithm.
  • Selection Algorithms: Like finding the k-th largest element.

Conclusion

Heap Sort is a powerful and efficient sorting algorithm, offering a reliable O(n log n) time complexity and in-place sorting. Its systematic approach using a binary heap makes it suitable for a variety of applications in computer science. By understanding the algorithmic details and implementation in C, you can leverage Heap Sort in your projects for efficient data sorting.

With this comprehensive guide, you should now have a solid foundation in Heap Sort, its implementation, and practical usage. Keep exploring and applying this knowledge to master the art of efficient sorting!

Subscribe to rahulv.dev | blog

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe