快速排序Q:有很多不同的键

Quicksort Q: Finitely many distinct keys

本文关键字:快速排序      更新时间:2023-10-16

需要展示一个具有特殊分区的快速排序,其中数组被划分为3个部分(<than 3 pivot,=to pivot、>than pivot)和一个大小为N的特殊数组,其中只有7个不同的键可以在O(N)中排序。

所以,我想我们可以假设枢轴被选择在中间的某个地方(否则我们可以有类似[0,1,2,3,4,5,6,6,5,…]的东西,这应该需要O(N^2))。

以下是我的想法:
假设我们进行了第一次分区。现在我们转到递归步骤2。假设我们只关注右边的分区。由于这里的每个元素都大于枢轴,并且只有7个不同的键,因此该分区中的不同键的数量严格小于7。这意味着算法经过7次迭代后,左、右子子系统中的所有元素都会被分解-分区应该相同。

现在,我可以看到,如果算法停止在常数数组上重复,这将是O(N),但我的理解是,它不是。如果不是这样,请澄清。

这是怎么回事?

快速排序算法如下所示:

quicksort(A, lo, hi):
  if lo < hi:
    p := partition(A, lo, hi)
    quicksort(A, lo, p - 1)
    quicksort(A, p + 1, hi)

我们有一个特殊的分区,它是3向的,所以假设它为它选择的任何枢轴返回相同的范围,我们只需要低于和高于这个范围:

quicksort(A, lo, hi):
  if lo < hi:
    p1, p2 := 3-way-partition(A, lo, hi)
    quicksort(A, lo, p1 - 1) // (1)
    quicksort(A, p2 + 1, hi) // (2)

现在,考虑最糟糕的情况。我们有一个看起来像[0,1,2,3,4,5,6,6,6,6...]的数组,我们的枢轴选择算法尽可能愚蠢:它以严格递增的顺序选择枢轴。在这种情况下,第一个递归调用(上面的(1))将始终不执行任何操作,因为没有比pivot更小的东西。因此,我们只处理一个大小为N - 1的递归调用。

每次递归调用都会将问题大小减少一个,直到第7次递归调用(将选择6枢轴)完成排序。这是只有7个不同键的关键步骤,您最多只需要7个调用。这7个调用中的每一个都会迭代整个数组。。。那是CCD_ 5。更一般地说,如果只有k不同的键,那么可以说最坏的情况是来自同一个参数的O(kN)