我读了this answer并找到了Quicksort的实现here.我还不清楚为什么Quicksort需要O(log n)额外的空间。
我理解调用堆栈是什么。我将上述实现应用于一组随机数,并查看了n - 1
的{{1}}次调用。
quickSort
我看到的输出:
[83,65,68,91,43,45,58,82]
快速排序。 left = 0 right = 7
快速排序。 left = 0 right = 6
快速排序。 left = 0 right = 4
快速排序。 left = 0 right = 3
快速排序。 left = 0 right = 2
快速排序。 left = 0 right = 1
快速排序。 left = 5 right = 6
[43,45,58,65,68,82,83,91]
这使得7(n-1)个电话。那么,如果调用的数量取决于public static void main(String[] args) {
Random random = new Random();
int num = 8;
int[] array = new int[num];
for (int i = 0; i < num; i++) {
array[i] = random.nextInt(100);
}
System.out.println(Arrays.toString(array));
quickSort(array, 0, array.length - 1);
System.out.println(Arrays.toString(array));
}
static int partition(int arr[], int left, int right) {
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2];
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
}
return i;
}
static void quickSort(int arr[], int left, int right) {
System.out.println("quickSort. left = " + left + " right = " + right);
int index = partition(arr, left, right);
if (left < index - 1)
quickSort(arr, left, index - 1);
if (index < right)
quickSort(arr, index, right);
}
,而不是n
,那么为什么quickSort需要为其调用堆栈提供O(log n)空间?
答案 0 :(得分:0)
我想我理解为什么在最坏的情况下Quicksort的堆栈大小为O(n)
。
要排序的数组的一部分(假设左)由一个元素组成,而另一部分(右)由n - 1
个元素组成。左侧部分的大小始终为1,右侧部分的大小每次减1。
因此,我们最初调用Quicksort,然后递归调用n - 1
次正确的部分。所以调用堆栈的额外空间是O(n)
。由于分区过程对每个递归调用都需要O(n)
,因此时间复杂度为O(n2)
。
至于平均案例分析,现在我不知道如何证明时间复杂度O(n * log n)
和额外空间O(log n)
。但是我知道如果我将输入数组分成两个几乎相等的部分,我会在左边部分调用Quicksort (log n) / 2
次。并且使用尾递归对正确的部分进行排序,而尾递归不会添加到调用堆栈中。
https://en.wikipedia.org/wiki/Quicksort
在这种情况下,Quicksort所需的额外空间为O (log n)
。遗漏了常数因子1/2
。
由于分区例程为n
,因此时间复杂度为O(n * log n)
。
如果我的假设是错误的,请纠正我。我已准备好阅读并接受你的回答。