Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does heap sort have a space complexity of O(1)?

I understand that both quick sort and merge sort need O(n) auxiliary space for the temporary sub-arrays that are constructed, and in-place quick sort requires O(log n) auxiliary space for the recursive stack frames. But for heap sort, it seems like it also has a worst case of O(n) auxiliary space to build the temporary heap, even if the nodes are just pointers to the actual elements.

I came across this explanation :

Only O(1) additional space is required because the heap is built inside the array to be sorted.

But I think this means the original array necessarily already had to be implemented as some sort of tree? If the original array was just a vector, it seems memory for a heap would still have to be allocated.

like image 682
Herman Tran Avatar asked Mar 06 '14 19:03

Herman Tran


People also ask

Why is heap sort space complexity O 1?

Since we cleverly reused available space at the end of the input array to store the item we removed, we only need O ( 1 ) O(1) O(1) space overall for heapsort.

Why is heap insert O 1?

The number of operations required depends only on the number of levels the new element must rise to satisfy the heap property, thus the insertion operation has a worst-case time complexity of O(log n) but an average-case complexity of O(1).

Does heap sort requires extra space?

Heapsort is a comparison-based sorting algorithm that uses a binary heap data structure. Like mergesort, heapsort has a running time of O ( n log ⁡ n ) , O(n\log n), O(nlogn), and like insertion sort, heapsort sorts in-place, so no extra space is needed during the sort.


1 Answers

Data in an array can be rearranged into a heap, in place. The algorithm for this is actually surprisingly simple., but I won't go into it here.

For a heap sort, you arrange the data so that it forms a heap in place, with the smallest element at the back (std::make_heap). Then you swap the last item in the array (smallest item in the heap), with the first item in the array (a largish number), and then shuffle that large element down the heap until it's in a new proper position and the heap is again a new min heap, with the smallest remaining element in the last element of the array. (std::pop_heap)

data:         1 4 7 2 5 8 9 3 6 0  make_heap:   [8 7 9 3 4 5 6 2 1 0] <- this is a min-heap, smallest on right  pop_heap(1): [0 7 9 3 4 5 6 2 1 8] <- swap first and last elements pop_heap(2): 0 [7 9 3 4 8 6 2 5 1] <- shuffle the 8 down the heap  pop_heap(1): 0 1 [9 3 4 8 6 2 5 7] <- swap first and last elements pop_heap(2): 0 1 [9 7 4 8 6 3 5 2] <- shuffle the 7 down the heap  etc 

So no data actually needs to be stored anywhere else, except maybe during the swap step.

For visualization, here's that original heap shown in a standard form

make_heap             0      2           1   3     4     5     6                8   7 9 pop_heap            8                           1                           1      2           1               2           8               2           5    3     4     5     6    ->   3     4     5     6    ->   3     4     8     6                     7 9                         7 9                         7 9 
like image 138
Mooing Duck Avatar answered Sep 23 '22 18:09

Mooing Duck