调用堆栈大小快速排序

时间:2015-06-09 19:35:37

标签: quicksort callstack space-complexity

我读了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)空间?

1 个答案:

答案 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)

enter image description here

如果我的假设是错误的,请纠正我。我已准备好阅读并接受你的回答。