基本思想

分治法。将数组分成两个小数组,对小数组进行归并排序,在合并两个小数组。

具体实现

  1. def merge(nums, p, q, r):
  2. left = [_ for _ in nums[p:q+1]]
  3. right = [_ for _ in nums[q+1:r+1]]
  4. left_len = q - p + 1
  5. right_len = r - q
  6. i, j, k = 0, 0, 0
  7. while i < left_len and j < right_len:
  8. if left[i] < right[j]:
  9. nums[p+k] = left[i]
  10. i += 1
  11. else:
  12. nums[p+k] = right[j]
  13. j += 1
  14. k += 1
  15. while i < left_len:
  16. nums[p+k] = left[i]
  17. i += 1
  18. k += 1
  19. while j < right_len:
  20. nums[p+k] = right[j]
  21. j += 1
  22. k += 1
  23. def _merge_sort(nums, p, r):
  24. if p < r:
  25. q = (p + r) // 2
  26. _merge_sort(nums, p, q)
  27. _merge_sort(nums, q+1, r)
  28. merge(nums, p, q, r)
  29. def merge_sort(nums):
  30. length = len(nums)
  31. _merge_sort(nums, 0, length-1)
  1. # merge的实现与上面相同
  2. def merge_sort(nums: List):
  3. length = len(nums)
  4. step = 1
  5. while step < length:
  6. offset = step * 2
  7. for i in range(0, length, offset):
  8. merge(nums, i, min(length-1, i+step-1), min(length-1, i+offset-1))
  9. step *= 2

性能分析

平均时间复杂度:

  • 归并排序 - 图1

最坏时间复杂度:

  • 归并排序 - 图2

空间复杂度:

  • 递归:归并排序 - 图3
  • 迭代:归并排序 - 图4

    优化

    在数组比较小时(比如小于20),可以用插入排序代替归并排序,以减小函数调用时间及合并数组时间。