快速排序算法 - 做同样事情的许多不同方法?

时间:2015-04-16 19:01:00

标签: algorithm sorting quicksort

我是否正确地说有很多方法可以执行快速排序?

对于参数sakes,让我们使用第一本教科书的数字: 20 47 12 53 32 84 85 96 45 18

这本书说交换了18和 20 (在书中,20是红色,18是蓝色,所以我加粗了20)。

基本上它一直在移动蓝色指针,直到数字为: 18 12 20 53 32 84 85 96 45 47

现在它说(这对我来说很明显),20左边的所有数字都小于,而右边的所有数字都大于,但它从未将20命名为“枢轴” ,这是大多数其他资源谈论它的方式。然后,正如所有其他方法所述,它在两侧进行快速排序,然后我们最终得到(它只包括排序列表的右半部分):

47 32 45 53 96 85 84,书结束了。现在我从其他资源中知道,一旦所有列表按顺序排列在一起。我想我明白这一点,但我常常被一本与第二本不同的“剑桥批准”教科书混淆。第二个是谈论通过选择中位数找到一个支点。

找到列表“枢轴”的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

从理论上讲 - 选择median元素作为枢轴可以保证最少的递归调用次数,并保证Theta(nlogn)运行时间。
然而,找到这个中位数是用selection algorithm完成的 - 如果你想保证选择需要线性时间 - 它需要median of medians算法,它的常数很差。

如果您选择第一个(或最后一个)元素作为数据透视表 - 您可以保证在排序或几乎排序的数组中获得较差的性能 - 这很可能是许多应用程序中的输入数组 - 所以这不是也是一个不错的选择。因此,选择数组的第一个/最后一个元素实际上是一个坏主意。

选择支点的一个很好的可靠解决方案是随机。从r = rand([0,length(array))中抽取一个随机数,并选择第r个元素作为您的支点。

虽然这里有最坏情况的理论可能性 - 但它是:

  1. 非常不可能
  2. 难以让恶意用户预测最坏情况输入是什么,特别是如果他不知道随机函数和/或种子。

答案 1 :(得分:2)

教科书中给出的内容类似于基于数据透视的概念,只是他们没有在那里提到这个术语。但是,无论如何,这些概念都是一样的。

  

找到列表“枢轴”的最佳方法是什么?

没有固定的方法来选择关键元素。您可以选择数组中的任何元素---第一个,第二个,最后一个等。它也可以随机选择给定的数组。

但是,科学家和数学家通常会谈论中间元素,它是基于对称性原因的列表的中间元素,从而减少了递归调用。

几乎可以看出,当你选择数组的第一个或最后一个元素时,会有更多的递归调用 - 从而更接近最坏的情况。将对更多的递归调用进行框架化,以便在两个分区上单独执行快速排序。