问题描述
我想知道运行时间与迭代合并和递归合并排序的不变性之间是否存在差异。如何以最好的情况与插入排序相同的方式更改合并排序(迭代或递归版本)?
解决方法
如果有伪代码,它将更具意义。 但是,迭代或递归实现的运行时间没有任何区别,唯一的区别是,与迭代实现相比,递归实现更具可读性和便利性。两种实现都有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))。
您可以修改合并排序算法,以在以较小的成本对大多数按升序或降序排序的数组上表现出更好的时间复杂度,同时使平均时间和最坏情况下的时间复杂度保持不变。 log(N)):
在合并阶段开始时添加一个额外的测试以验证两半是否已经订购,只是添加了N
测试,但降低了排序数组的线性 O(N)的复杂度
对于自上而下和自下而上的合并排序的另一种常见优化是,对于小于给定阈值的块,回退到插入排序。这不会改变平均时间复杂度,但可以将已排序或几乎已排序的数组的运行时间显着提高。
,要更改合并排序以获得O(n)的最佳情况时间,需要进行扫描以查看数据是否已排序。合并排序有多种形式,可以扫描数据以查找现有的排序运行,例如Timsort,但这是合并排序和插入排序的混合。
https://en.wikipedia.org/wiki/Timsort
如果排序不需要是稳定的(保留相等元素的顺序),则任何求反(data [i + 1] 纯合并排序的时间复杂度为O(n log(n)),移动次数始终相同,但是如果数据已经排序,则比较次数将减少约一半。