快速排序中的随机混乱如何帮助提高代码的效率?

时间:2014-12-25 08:18:39

标签: algorithm sorting shuffle

我正在阅读Robert Sedgwick关于算法的讲座视频,他解释说随机改组确保我们不会遇到快速排序中最坏情况的二次时间场景。但我无法理解如何。

5 个答案:

答案 0 :(得分:13)

虽然我们经常谈论平均案例复杂性,但我们实际上并不认为每个案例都会以相同的概率出现。

对已排序的数组进行排序是快速排序中最糟糕的情况,因为每当您选择一个数据透视图时,您会发现所有元素都放置在数据透视图的同一侧,因此您不能分成两个大致相等的一半一点都不而且在实践中,这种已经分类的案例会比其他案例更频繁地出现。

首先随机抽取数据是一种快速的方法,可以确保您确实最终以相同的概率出现所有情况,因此这种最坏的情况将与其他情况一样罕见。

值得注意的是,还有其他策略可以很好地处理已排序的数据,例如选择中间元素作为支点。

答案 1 :(得分:5)

假设最糟糕的情况 - 一切已经排序 - 经常值得担心,并且洗牌是一种黑魔法最省力的方式来避免这种情况而不必承认通过改进在这种情况下,您将问题转移到另一个问题,这恰好随机改组排序顺序。希望这种不良情况是一种非常罕见的情况,即使它确实出现了随机性,也意味着问题不能轻易复制并归咎于这种欺骗。

以牺牲罕见的方式为代价改善常见案例的概念很好。随机性作为实际考虑哪些案例或多或少会更常见的替代方案有点草率。

答案 2 :(得分:2)

在随机化QuickSort的情况下,由于枢轴元素是随机选择的,我们可以预期输入数组的分割相当平衡平均 - 与1和(1)的情况相反n-1)在非随机化版本的算法中分割。这有助于防止在不平衡分区中发生的QuickSort的最坏情况行为。

因此,随机版QuickSort的平均病例运行时间为O(nlogn)而不是O(n ^ 2);

答案 3 :(得分:0)

随机shuffle对输入空间的分布做了什么?为了理解这一点,让我们看一下在P集上定义的概率分布S,其中P不在我们的控制范围内。让我们通过应用P'S的随机随机播放来创建概率分布P。换句话说,每次我们从P获取样本时,我们都会将其统一随机地映射到S的元素。您对此产生的分布有什么看法P'

P'(x) = summation over all elements s in S of P(s)*1/|S| = 1/|S|

因此,P'只是S上的统一分布。随机shuffle使我们能够控制输入概率分布。

这与quicksort有什么关系?好吧,我们知道quicksort的平均复杂性。这是通过均匀概率分布计算出来的,这是我们想要在输入分布上保持的属性,而不管它到底是什么。为实现这一点,我们对输入数组进行随机抽取,确保分布不会以任何方式对抗。

答案 4 :(得分:-1)

视频是否在coursera? 不幸的是,shuffle 将性能降低到O(N ^ 2),数据为n,n,...,n,1,1,...,1。 我检查了Quick.java nn11.awk生成此类数据。

$ for N in 10000 20000 30000 40000; do time ./nn11.awk $N | java Quick; done | awk 'NF>1'

real    0m10.732s
user    0m10.295s
sys     0m0.948s

real    0m48.057s
user    0m44.968s
sys     0m3.193s

real    1m52.109s
user    1m48.158s
sys     0m3.634s

real    3m38.336s
user    3m31.475s
sys     0m6.253s