数据结构与算法演示台SUANFA.NET.CN · STEP BY STEP

排序 · 单步演示

归并排序

先把数组一直对半拆,拆到每段只剩一个数;再把相邻的两段有序段合并:每次比较两段的头,把小的那个写回原数组。

1 到 16 个整数(−99 到 999),用逗号或空格隔开。 输入只在你的浏览器里计算,不会上传。

380
121
712
53
444
265
906
177

当前操作已就位

步 001 / 055初始数组。归并排序先一路对半拆,拆到只剩一个数,再两两合并成有序段。

键盘: 单步,空格 播放/暂停(先点一下演示区)。

伪代码 · 当前行高亮

  1. 归并排序(lo, hi):
  2. if hi − lo < 1:return
  3. mid ← lo + ⌊(hi − lo) / 2⌋
  4. 归并排序(lo, mid);归并排序(mid+1, hi)
  5. L ← a[lo..mid];R ← a[mid+1..hi];k ← lo
  6. while L、R 都还有数
  7. 较小的头写到 a[k](相等取 L);k ← k+1
  8. 把没取完的那一段依次写回

变量

比较次数0
交换/写入次数0

复杂度

最好情况O(n log n)
平均情况O(n log n)
最坏情况O(n log n)
额外空间O(n)
稳定性稳定

拆分一共 ⌈log₂n⌉ 层,每层合并时每个数都被写回一次,所以每层 O(n)。合并需要额外的 L、R 数组,空间 O(n)。

要点

  • 运行时间几乎不受输入顺序影响,这是它和快速排序最大的区别。
  • 合并时相等取左边,就能保持稳定。
  • 链表排序常用归并:链表合并不需要额外数组。

常见错误

中点写成 (lo + hi) / 2 在一些语言里,lo + hi 可能超出整数范围;写成 lo + (hi − lo) / 2 更稳妥。

同一类的其他演示