如何解决快速排序到已排序的数组
此问题:https://www.quora.com/What-is-randomized-quicksort
Alejo Hausner告诉:在最坏的情况下,快速排序的成本,
具有讽刺意味的是,如果将quicksort应用于已排序的数组,则可能会得到这种代价高昂的行为
我不明白。有人可以向我解释。
https://www.quora.com/What-will-be-the-complexity-of-quick-sort-if-array-is-already-sorted可能是对此的答案,但这并没有给我完整的答复。
解决方法
根据实现方式,有几种“通用”方式来选择枢轴。
通常,对于“未分类”来源,没有选择它的好坏方法。 因此,某些实现只是将第一个元素作为枢轴。
对于已经分类的源,这会导致最坏的数据透视,因为这样的间隔永远都是空的。
->递归步骤= O(n)而不是所需的O(log n)。
这会导致O(n²)复杂性,这对于排序非常不利。
随机选择枢轴可避免这种情况。如上所述,在每次递归中随机选择的枢轴极不可能具有相同的不良特性。
由于您无法预测随机生成器的选择(如果是好的),因此不可能故意生成不良源
,Quicksort算法是这样的:
- 选择一个枢轴
- 将小于枢轴的元素移动到起点,将大于枢轴的元素移动到终点
- 现在数组看起来像
[<=p,<=p,p,>p,>p]
- 对数组的第一和第二“一半”进行递归排序
如果数据透视图始终总是靠近数组中间,那么Quicksort将非常有效,运行时间接近n log n
。如果枢轴是中间值,则此方法非常有效。但是,选择实际的中位数本身将是昂贵的。如果由于不幸而发生支点变化,成为数组中的最小或最大元素,您将得到一个像这样的数组:[p,>p]
。如果这种情况经常发生,则您的“快速排序”实际上就像选择排序一样。在那种情况下,由于要递归排序的子数组的大小在每次迭代时仅减少1,因此将有n
个迭代级别,每个级别都要花费n
个运算,因此总体复杂度为`n ^ 2。
现在,由于我们不愿意使用昂贵的操作来找到一个好的支点,因此我们不妨随机选择一个元素。而且由于我们也不在乎真正的随机性,所以我们可以从数组中选择任意元素,例如第一个。
如果随机地对数组进行随机混洗,那么选择第一个元素就很棒。您可以合理地希望它将定期为您提供“平均”元素。但是如果数组已经被排序了……那么根据定义,第一个元素是最小的。因此,在复杂度为n^2
的糟糕情况下。
避免“不良列表”的一种简单方法是选择一个真正的随机元素,而不是一个任意元素。或者,如果您有理由相信通常会在几乎已排序的列表上调用快速排序,则可以选择位置n/2
的元素,而不是位置1的元素。
也有几篇关于选择枢轴的不同方法的研究论文,其中包括对复杂性影响的精确计算。例如,您可以选择三个随机元素,将它们从最小到最大排列,并保持中间一个。但是得出的结论通常是:如果您尝试编写更好的枢轴选择,那么这样做也会更加昂贵,并且算法的整体复杂性不会得到太大改善。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。