我想展示Quicksort空间复杂性的最坏情况。
我正在考虑,Quicksort不使用辅助数组,它只是在Partition子例程上创建了一些辅助变量,而只是操作数组中的项。因此,很明显,我的结论是它使用了O(n)空间。
但是在互联网上搜索时,我发现Quicksort在最坏情况下的空间复杂度是O(log n)。
我只是不明白为什么在最坏的情况下它比输入数组占用更少的空间?
ps .:我正在关注“算法简介”这本书。
我已经尝试过的是计算算法中所有变量的声明。
QUICKSORT(A, p, r)
if p < r
q = partition(A, p, r)
QUICKSORT(A, p, q - 1)
QUICKSORT(A, q + 1, r)
PARTITION(A, p, r)
x = A[r] // pivot
i = p - 1
for j = p to r - 1
if A[j] <= x
i = i + 1
exchange A[i] with A[j]
exchange A[i + 1] with A[r]
return i + 1
答案 0 :(得分:1)
在评估空间复杂度时,您无需计算输入存储量,而是计算堆栈深度。
在直接QuickSort中,分区每次都可能非常不利,并且只能将子数组减少一个元素。因此,空间复杂度为 O(n)! (通常是大地震)。
因此,重要的是首先对最小的子数组进行递归并使用尾递归。这会将最坏的情况降低为 O(Log n)。
答案 1 :(得分:0)
如果您这样实现快速排序,则最坏的情况是空间复杂度为O(n):
QUICKSORT(A, p, r)
if p < r
q = partition(A, p, r)
QUICKSORT(A, p, q - 1)
QUICKSORT(A, q + 1, r)
但是,快速排序的真正实现绝不会以这种方式编写。他们是这样写的:
QUICKSORT(A, p, r)
while p < r
q = partition(A, p, r)
if (q-p <= r-q)
QUICKSORT(A, p, q - 1)
p = q+1
else
QUICKSORT(A, q + 1, r)
r = q-1
就像@YvesDoust所说的那样,重要的是递归到较小的部分,然后在较大的部分循环(或尾随递归,但这是另一回事)。
这样,每个递归调用的范围最多为调用者范围的一半,最大深度为O(log n)
答案 2 :(得分:0)
在最坏的情况下,空间复杂度是O(n),而不是O(log n),也就是说,分区总是不平衡的。例如,一个分区的大小始终为k,另一个分区的大小始终为nk,其中k为常数(例如1、2或3),n为在每一轮分区中要分区的数组的大小。递归。
换句话说,在最坏的情况下,在每一轮递归中,总是存在一个大小小于等于k的分区(较小的值,例如1、2或3)。在这种情况下,另一个分区的大小线性减小(减小k)。因此,您需要递归O(n / k)个回合。
如果在最坏的情况下可以为空间复杂度递归O(log n)回合,但为时间复杂度又需要O(n)回合,那将是不合逻辑的。