【发布时间】:2020-08-20 09:36:34
【问题描述】:
我想知道迭代和递归合并排序的运行时间和不变量之间是否存在差异。如何更改 Merge 排序(迭代或递归版本),以使最佳情况与插入排序相同?
【问题讨论】:
-
请展示您已经完成的一些工作以了解自己,以及您在理解方面遇到的具体问题
标签: algorithm sorting mergesort
我想知道迭代和递归合并排序的运行时间和不变量之间是否存在差异。如何更改 Merge 排序(迭代或递归版本),以使最佳情况与插入排序相同?
【问题讨论】:
标签: algorithm sorting mergesort
如果有伪代码那就更有意义了。 然而,迭代或递归实现的运行时间没有任何区别,唯一的区别是,与迭代相比,递归实现更具可读性和方便性。两种实现都有O(nLogn) 运行时间。
如何在这种情况下更改合并排序(迭代或递归版本) 一种最佳情况与插入排序相同的方式
合并排序对输入是中性的,这意味着无论是排序的还是未排序的输入都会有O(nLogn),所以没有最好的情况或最坏的情况,总是O(nLogn)。
另一方面,插入排序对输入不是中性的,这意味着,在最好的情况下,当输入被排序时它有 O(n) 运行时间,而在最坏的情况下,当输入被反向排序时它是 O(n^2) .
我想知道运行时间之间是否存在差异 以及迭代和递归合并排序的不变量。
在计算机科学中,循环不变量是程序循环的属性 在每次迭代之前都是如此。 link
iterative 实现不变量
curr_size<=n-1
left_start<n-1
【讨论】:
迭代和递归合并排序变体,也称为自顶向下和自底向上合并排序,具有相同的时间复杂度O(N.log(N))和稳定性。运行时间可能会受到执行质量的影响,尤其是缓存友好性、工作空间分配方法的效率以及自下而上合并的片段大小的有效平衡,这在自上而下的合并排序中是自动的。一个有趣且有时有用的属性是时间复杂度不依赖于实际的数据分布。经典实现中没有最佳情况和最坏情况,只有O(N.log(N))的恒定时间复杂度。
您可以修改归并排序算法,以在大多数以升序或降序排序的数组上表现出更好的时间复杂度,同时保持相同的平均和最坏情况时间复杂度 O(N.日志(N)):
在合并阶段开始时添加一个额外的测试来验证两半是否已经排序只需添加 N 测试,但将排序数组的复杂度降低到线性 O(N)。
自上而下和自下而上合并排序的另一个常见优化是回退到对小于给定阈值的块的插入排序。这不会改变平均时间复杂度,但会显着提高排序或几乎排序数组的运行时间。
【讨论】:
要更改合并排序以获得 O(n) 的最佳情况时间,需要进行扫描以查看数据是否已经排序。合并排序有多种变体,可以扫描数据以查找现有的排序运行,例如 Timsort,但这是合并排序和插入排序的混合体。
https://en.wikipedia.org/wiki/Timsort
如果排序不需要稳定(保持相等元素的顺序),那么任何反转(data[i+1]
纯归并排序的时间复杂度为O(n log(n)),移动的次数总是一样的,但是如果数据已经排序,那么比较的次数会减少一半左右。
【讨论】: