回答
我分成2n个子列表的列表(大小为N)(使用基于零的索引):
列表0:0的元素,2N,4N,...
列表1:元素1 ,2N + 1,N + 1,...
...
列表2N-1:元素2N-1,4N-1,...
每个显然排序。
现在合并这些列表(每次重复合并2个列表,或使用每个列表中的一个元素使用最小堆)。
就这些。时间复杂度为O(N log(n))。
这很容易在Python:
>>> a = [1, 0, 5, 4, 3, 2, 6, 8, 9, 7, 12, 13, 10, 11]
>>> n = max(abs(i - x) for i, x in enumerate(a))
>>> n
3
>>> print(*heapq.merge(*(a[i::2 * n] for i in range(2 * n))))
0 1 2 3 4 5 6 7 8 9 10 11 12 13
Heap Sort对于最初的随机数组/元素集合非常快。
# heapify
for i = n/2:1, sink(a,i,n)
→ invariant: a[1,n] in heap order
# sortdown
for i = 1:n,
swap a[1,n-i+1]
sink(a,1,n-i)
→ invariant: a[n-i+1,n] in final position
end
# sink from i in a[1..n]
function sink(a,i,n):
# {lc,rc,mc} = {left,right,max} child index
lc = 2*i
if lc > n, return # no children
rc = lc + 1
mc = (rc > n) ? lc : (a[lc] > a[rc]) ? lc : rc
if a[i] >= a[mc], return # heap ordered
swap a[i,mc]
sink(a,mc,n)
对于不同的情况下,像“近排序”“一些独特”的算法可以不同的方式工作是比较有效:在伪代码如下这种将imlemented。有关各种情况下带动画的算法的完整列表,请参阅this brilliant site。
我希望这会有所帮助。
Ps。对于几乎排序的集合(如上所述),插入排序是您的赢家。
我推荐使用comb sort,只需以等于最大距离(或在那里)以上的间隙大小开始。期望O(n log n)(或者在你的情况下,O(n log d),其中d是最大位移),易于理解,易于实现,并且即使在元素移位超过预期时也能工作。如果你需要有保证的执行时间,你可以使用像堆排序这样的东西,但是在过去,我发现空间或计算时间的开销通常不值得,并最终实现其他任何事情。
由于each integer being at most n positions away from its final position
:
1)的最小整数(又名最终排序后的数组中第0个整数),其当前的位置必须在A [0 ... n]中,因为第n个元素与第0个位置相距n个位置
2)第二小的整数(也就是最后一个排序数组中的第一个整数,基于零)位置必须在A [0 ... n + 1]
3)对于第i个最小整数,它的当前位置必须在A [i-n ...i + n]
我们可以使用一个(n + 1)大小最小的堆,它包含一个滚动窗口来获取数组。你可以在这里找到更多的细节:
- 1. 最小化n个有序整数的k个整数的方差
- 2. 什么是少数整数最快的排序算法?
- 3. 算法重排列整数
- 4. M的计算在LCM N个整数
- 5. Java程序将整数的倒数加起来最多为n
- 6. 使用只有整数算术计算N个整数的平均值,并且不保留N个值
- 7. 为什么这种排序算法只排序为最终整数的值?
- 8. 算法在整数数组中的最大整数
- 9. 在大小为N的未排序数组中查找K个最小整数
- 10. 排序多维数组的整数值
- 11. 有限制排序整数
- 12. 鉴于2个排序的整数数组,发现在次线性时间的第n个数量最多
- 13. 算法整数
- 14. 算法整数
- 15. 排序三个整数
- 16. 排序数组的整数
- 17. 排序的旋转整数数组,搜索算法
- 18. 排序在C#多维[,]数组,整数
- 19. 用Javascript排序多维数组:整数
- 20. KornShell整数排序
- 21. 计算整数和一个浮点数
- 22. 用于N个整数的随机置换的在线算法
- 23. 具有分组约束的前n个整数的排列
- 24. 如何计算O(N)中未排序整数数组的模式?
- 25. 随机生成一个可被N整除的数字的最佳算法
- 26. Swap整数算法
- 27. 如何使用现有的整数排序对整数元组进行排序?
- 28. 计算2个整数坐标点之间距离的最有效方法是?
- 29. 部分排序为N个未排序组的有效算法
- 30. 用数组排序整数。
你需要尽可能最好的排序算法,或者只是一个好?许多着名的排序利用“接近排序的”列表(或者可以调整为这样做),并且性能接近O(n),所以如果你不需要尽可能好的排序,就使用其中的一个。 – 2012-04-05 18:59:59
所以像插入排序(几乎排序列表上运行良好)就可以做到这一点。那么“最好的排序”呢?或者很难证明/获得? – darksky 2012-04-05 19:03:04
这不是很好定义,因为_any_列表中的_all_元素最多有n个位置远离任何其他位置。罗素是正确的,如果有什么东西,使您的排序要求独特这应该用于确定哪种算法将最适合特定情况下... – MoonKnight 2012-04-05 19:05:05