我一直在比较各种枢轴选择算法的运行时间。令人惊讶的是,总是选择第一个元素的最简单的是最快的。这可能是因为我用随机数据填充数组。
如果阵列已被随机化(改组)重要吗?例如,选择3的介质作为枢轴始终(?)比选择第一个元素作为枢轴更好。但这并不是我所注意到的。是因为如果数组已经被随机化,那么没有理由假设排序,并且使用媒介假设存在某种程度的排序?
答案 0 :(得分:1)
快速排序的最坏情况运行时为O(n²)
。 Quicksort只是一种平均情况下的快速排序算法。
要达到O(n log n)
的平均运行时,您必须选择随机数据元素。
但是,您可以随机播放列表并选择第一个元素,而不是选择随机数据元素
要看到这种情况,你可以这样看待:让我们说所有元素都按照特定的顺序排列。改组意味着您在元素列表中使用随机排列,因此随机元素将位于第一个位置,也位于所有其他位置。你也可以通过随机选择第一个元素的所有元素之一,然后为第二个元素随机选择另一个元素(尚未共同元素)来混淆列表,以此类推。
如果您的列表已经是一个随机生成的列表,您可以直接选择第一个元素作为数据透视,而不会再次进行洗牌。
因此,选择第一个元素是最快的因为随机生成的输入,但选择thrid或者last也与选择第一个元素一样快。
选择枢轴元素的所有其他方法都必须计算某些东西(中位数或随机数或类似的东西),但它们没有优于随机选择的优势。
答案 1 :(得分:1)
响应时间很晚,但我相信它会增加一些额外信息。
令人惊讶的是,总是选择第一个元素的最简单的一个 是最快的。
这实际上并不奇怪,因为您提到使用随机数据测试算法。实际上,几乎排序和排序的数据的百分比远远大于统计预期的数据。以时间顺序数据为例,当您将其收集到日志文件中时,某些元素可能会出现故障,但大多数元素已经排序。不幸的是,以第一个(或最后一个)元素为枢轴的Quicksort实现很容易受到此类输入的影响,并且它会退化为O(n^2)
复杂度,因为在分区步骤中,您将数组划分为两半大小1
和n-1
,因此您平均得到n
个分区,而不是log n
。
这就是为什么人们决定添加某种随机化的原因,这种随机化可能会使问题输入尽可能地最小化。有三种众所周知的方法:
改变输入 - 引用罗伯特塞奇威克,“用这种方法获得O(n^2)
表现的可能性低于你被雷击击中的可能性”:)
随机选择枢轴元素 - 维基百科说平均而言,在这种情况下预期的比较次数为1.386 n log n
选择枢轴元素作为三个中位数 - 维基百科说平均而言,在这种情况下预期的比较数为1.188 n log n
然而,随机化成本。如果您对输入数组进行随机播放,O(n)
由O(nlogn)
控制,但您需要在帐户中承担调用random(..)
方法n
次的费用。通过简单的方法,可以避免这种情况,因此更快。
另见: