运行 迭代合并排序的时间和不变量是多少?
What is the running time and invariants of iterative merge sort?
我想知道 运行 次与迭代和递归合并排序的不变量之间是否存在差异。如何以最佳情况与插入排序相同的方式更改合并排序(迭代或递归版本)?
如果有伪代码,那就更有意义了。 但是,迭代或递归实现的运行次没有任何区别,唯一的区别是,递归实现比迭代实现更具可读性和方便性。两种实现都有 O(nLogn)
运行 时间。
How to change the Merge sort (iterative or recursive version) in such
a way that the best case is the same as in the case of Insertion sort
合并排序对输入是中性的,这意味着排序或未排序的输入都会有 O(nLogn)
,所以没有最好的情况或最坏的情况,总是 O(nLogn)
。
另一方面,插入排序对输入不是中性的,这意味着在最好的情况下它有 O(n)
运行 时间对输入进行排序,在更坏的情况下当输入被反向排序时是 O(n^2)
。
I wanted to know that if there is a difference between running times
and invariants of iterative and recursive merge sort.
In computer science, a loop invariant is a property of a program loop
that is true before each iteration. link
iterative实现不变
curr_size<=n-1
left_start<n-1
迭代和递归归并排序变体,也称为 top-down 和 bottom-up 归并排序具有相同的时间复杂度 O(N.log(N)) 稳定。 运行 时间可能会受到实施质量的影响,尤其是缓存友好性、工作 space 分配方法的效率以及 bottom-up 合并的片段大小的有效平衡,这在 top-down归并排序。一个有趣且有时有用的 属性 是时间复杂度不依赖于实际数据分布。在经典实现中没有最佳情况和最坏情况,只有O(N.log的恒定时间复杂度(N)).
您可以修改合并排序算法,以便以较小的成本在大多数按升序或降序排序的数组上表现出更好的时间复杂度,同时保持相同的平均和最坏情况时间复杂度 O(N.log(N)):
在合并阶段开始时添加一个额外的测试来验证两半是否已经排序只是添加 N
测试但将复杂度降低到线性 O(N) 用于排序数组。
top-down 和 bottom-up 合并排序的另一个常见优化是对小于给定阈值的块回退到插入排序。这不会改变平均时间复杂度,但会在已排序或几乎已排序的数组上显着提高 运行 时间。
要更改合并排序以获得 O(n) 的最佳情况时间,需要进行扫描以查看数据是否已排序。有一些合并排序的变体可以扫描数据以找到现有的已排序 运行s,例如 Timsort,但它是合并排序和插入排序的混合体。
https://en.wikipedia.org/wiki/Timsort
如果排序不需要稳定(保留相等元素的顺序),那么任何反转(data[i+1] < data[i])都可以被视为已排序运行边界。如果排序需要稳定,则需要一些方法来跟踪 运行 边界(例如索引或指针数组)。
纯归并排序的时间复杂度为O(n log(n)),移动次数始终相同,但如果数据已经排序,则比较次数减少一半左右。
我想知道 运行 次与迭代和递归合并排序的不变量之间是否存在差异。如何以最佳情况与插入排序相同的方式更改合并排序(迭代或递归版本)?
如果有伪代码,那就更有意义了。 但是,迭代或递归实现的运行次没有任何区别,唯一的区别是,递归实现比迭代实现更具可读性和方便性。两种实现都有 O(nLogn)
运行 时间。
How to change the Merge sort (iterative or recursive version) in such a way that the best case is the same as in the case of Insertion sort
合并排序对输入是中性的,这意味着排序或未排序的输入都会有 O(nLogn)
,所以没有最好的情况或最坏的情况,总是 O(nLogn)
。
另一方面,插入排序对输入不是中性的,这意味着在最好的情况下它有 O(n)
运行 时间对输入进行排序,在更坏的情况下当输入被反向排序时是 O(n^2)
。
I wanted to know that if there is a difference between running times and invariants of iterative and recursive merge sort.
In computer science, a loop invariant is a property of a program loop that is true before each iteration. link
iterative实现不变
curr_size<=n-1
left_start<n-1
迭代和递归归并排序变体,也称为 top-down 和 bottom-up 归并排序具有相同的时间复杂度 O(N.log(N)) 稳定。 运行 时间可能会受到实施质量的影响,尤其是缓存友好性、工作 space 分配方法的效率以及 bottom-up 合并的片段大小的有效平衡,这在 top-down归并排序。一个有趣且有时有用的 属性 是时间复杂度不依赖于实际数据分布。在经典实现中没有最佳情况和最坏情况,只有O(N.log的恒定时间复杂度(N)).
您可以修改合并排序算法,以便以较小的成本在大多数按升序或降序排序的数组上表现出更好的时间复杂度,同时保持相同的平均和最坏情况时间复杂度 O(N.log(N)):
在合并阶段开始时添加一个额外的测试来验证两半是否已经排序只是添加 N
测试但将复杂度降低到线性 O(N) 用于排序数组。
top-down 和 bottom-up 合并排序的另一个常见优化是对小于给定阈值的块回退到插入排序。这不会改变平均时间复杂度,但会在已排序或几乎已排序的数组上显着提高 运行 时间。
要更改合并排序以获得 O(n) 的最佳情况时间,需要进行扫描以查看数据是否已排序。有一些合并排序的变体可以扫描数据以找到现有的已排序 运行s,例如 Timsort,但它是合并排序和插入排序的混合体。
https://en.wikipedia.org/wiki/Timsort
如果排序不需要稳定(保留相等元素的顺序),那么任何反转(data[i+1] < data[i])都可以被视为已排序运行边界。如果排序需要稳定,则需要一些方法来跟踪 运行 边界(例如索引或指针数组)。
纯归并排序的时间复杂度为O(n log(n)),移动次数始终相同,但如果数据已经排序,则比较次数减少一半左右。