为什么MergeSort的奇数拆分“更快”?

问题描述

|   MergeSort是一种分而治之的算法,可将输入分为几个部分,然后递归求解。      ...分割功能有几种方法。一种方法是拆分中间部分。该方法具有一些不错的属性,但是,我们将重点介绍一种更快的方法:奇偶拆分。想法是将每个偶数位置元素放在一个列表中,将每个奇数位置元素放在另一个列表中。 这直接来自我的讲义。到底为什么奇数拆分比数组中间快呢? 我猜测这与传递到MergeSort的列表有关,并且已经具有已经排序的质量,但是我不确定。 有人能对此有所启示吗? 编辑:我尝试在Python中运行以下命令...
global K
K = []
for i in range (1,100000):
    K.append(i)


def testMergeSort():
\"\"\"
testMergeSort shows the proper functionality for the
Merge Sort Algorithm implemented above.
\"\"\"

t = Timer(\"mergeSort([K])\",\"from __main__ import *\")
print(t.timeit(1000000))

p = Timer(\"mergeSort2([K])\",\"from __main__ import *\")
print(p.timeit(1000000))
(MergeSort是奇数个MergeSort,MergeSort2划分中心) 结果是:               0.771506746608              0.843161219237             

解决方法

我可以看到有更好的可能,因为用替代元素将其拆分意味着您不必知道输入要花多长时间-您只需将元素放入交替列表中,直到用完为止。 如果您仔细考虑允许进行更好的并行处理,则还可以在完成遍历第一个列表之前开始拆分结果列表。 我应该补充一点,我不是这些问题的专家,这只是我想到的事情...     ,输入列表离已排序的对象越近,运行时间越短(这是因为如果一切都已经按正确的顺序进行,则
merge
过程不必to2ѭ任何值;它只是执行O(n)比较由于MergeSort在拆分的每一部分都以递归方式调用自己,因此我们希望选择一个
split
函数,以增加列表中所得的两半按排序顺序排列的可能性。比拆开中间部分做得更好。例如,
MergeSort([2,1,4,3,5,7])
会导致
Merge(MergeSort([2,4]),MergeSort([3,7]))
如果我们拆分中间部分(请注意,两个子列表都存在排序错误),而如果我们进行偶数拆分,则会得到
Merge(MergeSort([2,5]),MergeSort([1,7]))
这样就得到了两个已经排序的列表(以及随后调用ѭ7calls的最佳情况)。在不了解输入列表的情况下,分割函数的选择不应渐近地影响运行时。     ,我怀疑您的实验中有噪音。 :)其中一些可能来自比较交换,实际上并未移动列表中的任何元素,从而避免了缓存失效等。 无论如何,这里有一个关于此的聊天:https://cstheory.stackexchange.com/questions/6732/why-is-an-even-odd-split-faster-for-mergesort/6764#6764(是的,我确实在此处发布了类似的答案(完整披露)) 维基百科上的相关文章指出,mergesort为O(n log(n)),而奇偶合并排序为O(n log(n)^ 2)。奇偶甚至肯定是“较慢的”,但排序网络是静态的,因此您始终知道要执行的操作,并且(查看Wikipedia条目中的图形)注意到算法如何保持并行直到结束。 当合并排序最终将2个列表合并在一起时,奇偶合并排序的8元素排序网络的最后比较仍然是独立的。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...