Exploring Time and Space Complexities of Heap Sort
This article is a complementary resource to the DSA with Python and DSA with C++ courses.
This article is a complementary resource to the DSA with Python and DSA with C++ courses.
Heap sort is a comparison-based sorting algorithm that uses a binary heap data structure.
It works by first building a max heap (or min heap) from the input array and then repeatedly extracting the maximum (or minimum) element from the heap to build the sorted array.
def heapify(arr, n, i):
largest = i # Initialize largest as root
left = 2 * i + 1 # Left child
right = 2 * i + 2 # Right child
# Check if left child exists and is larger than root
if left < n and arr[left] > arr[largest]:
largest = left
# Check if right child exists and is larger than root
if right < n and arr[right] > arr[largest]:
largest = right
# If largest is not root, swap and heapify the affected subtree
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(arr):
n = len(arr)
# Build max heap
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# Extract elements from the heap one by one
for i in range(n - 1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # Move current root to end
heapify(arr, i, 0) # Heapify the reduced heap
return arr
template<typename T>
void heapify(std::vector<T>& 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) {
std::swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
template<typename T>
void heap_sort(std::vector<T>& arr) {
int n = arr.size();
// 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) {
std::swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
Time complexity: O(nlogn)
In all cases, heap sort's time complexity is O(nlogn)
.
This is because heap sort involves two parts:
Suppose we need to sort the following array in descending order:
3, 7, 5, 1, 9, 2, 8, 6, 4
First, we need to heapify the array to build the following max heap:
9, 7, 8, 6, 5, 2, 3, 1, 4
After extracting the largest element (9), the heap is rearranged, and heapify operations continue.
So, for this array of size 9, we'll need to heapify the tree eight times on top of an additional heapify to build the heap.
So, for an array of size n
, we'll heapify the tree n
times. As each heap operation costs O(logn)
, n
heap operations will thus cost O(nlogn)
.
Since the cost of extracting the root is O(1)
, we can ignore it to count the total time complexity of heap sort as O(nlogn)
in all cases.
Heap sort is an in-place sorting algorithm, i.e., it sorts the elements within the original array without requiring any significant additional memory allocation.
The only extra variables we need are those required for the heapify process, whose number remains constant regardless of the size of the array.
Therefore, the space complexity is O(1)
, making heap sort memory efficient.
Heap sort is particularly useful when space efficiency is critical and in cases where a stable sorting algorithm is not required.
It is also useful when we need a sorting algorithm that performs consistently well, even for large datasets.
When to Use:
O(nlogn)
time complexity in all cases.When to Avoid: