Sorting 为什么堆排序的空间复杂度为O(1)?

Sorting 为什么堆排序的空间复杂度为O(1)?,sorting,complexity-theory,time-complexity,Sorting,Complexity Theory,Time Complexity,我知道快速排序和合并排序都需要O(n)辅助空间用于构建的临时子数组,就地快速排序需要O(log n)辅助空间用于递归堆栈帧。但是对于堆排序,它似乎还有一个最坏的情况,即O(n)辅助空间来构建临时堆,即使节点只是指向实际元素的指针 我遇到了这样一个问题: 由于堆构建在要排序的数组中,因此只需要0(1)个额外的空间 但我认为这意味着原始数组必须已经实现为某种树?如果原始数组只是一个向量,那么堆的内存似乎仍然需要分配。这里的酷技巧是,因为堆是一个完整的二叉树,您可以只使用一个普通数组,对于项i,它的父

我知道快速排序和合并排序都需要
O(n)
辅助空间用于构建的临时子数组,就地快速排序需要
O(log n)
辅助空间用于递归堆栈帧。但是对于堆排序,它似乎还有一个最坏的情况,即
O(n)
辅助空间来构建临时堆,即使节点只是指向实际元素的指针

我遇到了这样一个问题:

由于堆构建在要排序的数组中,因此只需要0(1)个额外的空间


但我认为这意味着原始数组必须已经实现为某种树?如果原始数组只是一个向量,那么堆的内存似乎仍然需要分配。

这里的酷技巧是,因为堆是一个完整的二叉树,您可以只使用一个普通数组,对于项i,它的父项是项
i/2
数组中的数据可以就地重新排列到堆中。这个算法实际上非常简单,但我在这里不赘述

对于堆排序,您可以安排数据,使其在适当的位置形成一个堆,最小的元素在后面(
std::make_heap
)。然后将数组中的最后一个项(堆中最小的项)与数组中的第一个项(较大的数字)交换,然后将该大元素向下移动堆,直到它位于新的正确位置,堆再次成为新的最小堆,剩余的最小元素位于数组的最后一个元素中。(
std::pop_heap

}

i/p存储在数组中,该数组被传递给堆排序算法- 堆排序(A)。数组A被解释为树,并在构建后从中取出MAX-HEAP和 将最后一个元素与根交换,每次将堆的大小减小一,然后对其调用MAX-HEAPIFY(A,1)

这是我们仅在该数组(A)内执行的所有操作,该数组作为i/p to算法给出。执行此操作时,我们没有使用任何额外空间。。
所以空间复杂度-O(1)。

堆排序是一种就地算法;它不需要任何额外的空间。元素在每次递归期间仅在同一数组内重新排列


它提供了一种感觉,即正在形成一个二进制堆或树,但在实际场景中,没有形成任何树或堆。

@MooingDuck我同意你的看法。虽然知道答案的人马上就会明白。@RikayanBandyopadhyay:“在你理解递归之前,你必须先理解递归”谢谢你,这也很有帮助。这根本没有回答问题。很好。它是一个很酷的属性,允许我们在数组内部构建一个堆来进行排序。我想补充一点,堆可以被认为是一个完整的二叉树,其中除最后一个可能之外的所有级别都被填充,节点尽可能地位于左侧。完整的二叉树表示该树在所有级别上都已完全填充。感谢您的解释和示例!出色的回答和形象化。保存的!如果它不在合适的位置,就不能快速排序。你也可以在适当的地方合并。用恒定的辅助空间进行快速排序是可能的,但是它变得很奇怪,以至于很多程序员都怀疑它是否仍然是一个快速排序。
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
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
HEAP-SORT(A)
{
BUILD-MAX-HEAP(A)
if(i= A.length down to 2)
    exchange A[i] with A[1]
    A.heapSize = A.heapSize-1
    MAX-HEAPIFY(A,1)