试图理解快速排序的复杂性

时间:2016-10-28 05:21:50

标签: java arrays algorithm sorting quicksort

我知道最坏的情况发生在枢轴是最小或最大的元素时。然后其中一个分区为空,我们重复N-1个元素的递归

但如何计算O(N^2)

我读过一些文章仍然无法完全理解。

类似地,最好的情况是当枢轴是阵列的中值并且左右部分具有相同的大小时。但是,那么如何计算值O(NlogN)

5 个答案:

答案 0 :(得分:2)

  

我知道最坏的情况发生在枢轴是最小或最大的元素时。然后其中一个分区为空,我们重复N-1个元素的递归。

所以,想象一下你反复挑选最糟糕的支点;即在N-1情况下,一个分区是空的,你用N-2元素递归,然后是N-3,依此类推,直到你达到1.

N-1 + N-2 + ... + 1的总和为(N * (N - 1)) / 2。 (学生们现在通常在高中数学中学到这一点......)

O(N(N-1)/2)O(N^2)相同。您可以从Big-O表示法的数学定义中的第一原理推导出这一点。

  

类似地,最好的情况是当枢轴是阵列的中值并且左右部分具有相同的大小时。但是,那么如何计算值O(NlogN)。

这有点复杂。

将问题想象成一棵树:

  • 在顶层,您将问题拆分为两个大小相等的子问题,并将N个对象移动到正确的分区中。

  • 在第二级。将两个子问题分成四个子问题,在2个问题中,将N / 2个对象移动到正确的分区中,总共移动了N个对象。

  • 在底层,您有大小为2的N / 2子问题,您(理论上)将其分成N个大小为1的问题,再次复制N个对象。

显然,在每个级别移动N个对象。对于大小为N的问题,树的高度是log 2 N.所以...有N * log 2 N个对象移动;即O(N * log 2

但是log 2 N是log e N * log e 2。 (高中数学,再次。)

所以O(Nlog 2 N)是O(NlogN)

答案 1 :(得分:1)

对你的陈述稍作修改:

  

我知道最坏的情况发生在枢轴是最小或最大的元素时。

实际上,最糟糕的情况发生在每个连续的枢轴是剩余分区数组的最小或最大元素时。

为了更好地理解最坏的情况:想想已经排序的数组,您可能正在尝试排序。

您选择第一个元素作为第一个数据透视。在比较数组的其余部分后,您会发现n-1元素仍然位于另一端(右侧),并且第一个元素保持在同一位置,这实际上完全胜过分区的目的。这些步骤将持续重复,直到最后一个元素具有相同的效果,这反过来将考虑(n-1 + n-2 + n-3 + ... + 1)比较,并总计(n*(n-1))/2比较。所以,

O(n*(n-1)/2) = O(n^2) for worst case.

为了解决这个问题,我们总是建议随机随机选择

我会尝试为平均情况添加解释。

答案 2 :(得分:0)

最好的情况可以来自Master定理。例如,请参阅https://en.wikipedia.org/wiki/Master_theorem或Cormen,Leiserson,Rivest和Stein:算法简介以获得定理证明。

答案 3 :(得分:0)

首先,在此处粘贴伪代码:

enter image description here

enter image description here

在我看来,你需要了解这两种情况:最坏的情况和最好的情况。

  • 最糟糕的情况: 当轴将列表分成两个大小为0和n-1的子列表时,会发生最不平衡的分区。递归的复杂性是T(n)= O(n)+ T(0)+ T(n-1)= O(n)+ T(n-1)。 主定理告诉我们 T(N)= O(N²)。
  • 最好的情况: 在最平衡的情况下,每次我们执行分区时,我们将列表分成两个几乎相等的部分。与最差相同,递归关系是T(n)= O(n)+ 2T(n / 2)。它可以转换为T(n)= O(n logn)。

答案 4 :(得分:0)

考虑它的一种方法如下。

如果quicksort对枢轴做出不好的选择,则枢轴会引起不平衡的分区,大部分元素位于枢轴的一侧(低于或高于)。在极端情况下,您可以按照建议将所有元素都放在枢轴下方或上方。在这种情况下,我们可以使用重复T(n)=T(1)+T(n-1)+O(n)来模拟快速排序的时间复杂度。但是,T(1)=O(1),我们可以写出重复T(n)=O(n)+O(n-1)+...+O(1) = O(n^2)。 (一个人必须要注意理解Big-Oh术语的含义。)

另一方面,如果quicksort反复做出好的枢轴选择,那么这些枢轴会引起平衡的分区。在最好的情况下,大约一半的元素将位于枢轴下方,大约一半的元素位于枢轴上方。这意味着我们在两个大小相等的子阵列上进行递归。然后重复出现T(n)=T(n/2)+T(n/2)+O(n) = 2T(n/2)+O(n)。 (如果一个人想要正式的话,也必须注意舍入n/2。)这解决了T(n)=O(n log n)

最后一段的直觉是我们在排序顺序中计算枢轴的相对位置,而不实际排序整个数组。然后我们可以计算下面子阵列中枢轴的相对位置,而不必担心上面子阵列中的元素;类似于上述子阵列。