跳到主要内容

归并排序

归并排序(Merge Sort)是一种高效的排序算法,采用分治法(Divide and Conquer)的思想。它将一个数组分成两个子数组,分别对子数组进行排序,然后将排序后的子数组合并成一个有序的数组。归并排序的时间复杂度为 O(n log n),是一种稳定的排序算法。

基本概念

归并排序的核心思想是“分而治之”。具体步骤如下:

  1. 分解:将数组递归地分成两个子数组,直到每个子数组只包含一个元素。
  2. 合并:将两个有序的子数组合并成一个有序的数组。

分治法

分治法是一种递归的算法设计方法,它将问题分解成多个相似的子问题,递归地解决这些子问题,然后将子问题的解合并成原问题的解。

代码示例

以下是归并排序的 Python 实现:

python
def merge_sort(arr):
if len(arr) <= 1:
return arr

mid = len(arr) // 2
left_half = merge_sort(arr[:mid])
right_half = merge_sort(arr[mid:])

return merge(left_half, right_half)

def merge(left, right):
sorted_array = []
i = j = 0

while i < len(left) and j < len(right):
if left[i] < right[j]:
sorted_array.append(left[i])
i += 1
else:
sorted_array.append(right[j])
j += 1

sorted_array.extend(left[i:])
sorted_array.extend(right[j:])

return sorted_array

输入与输出

假设我们有一个未排序的数组 [38, 27, 43, 3, 9, 82, 10],使用归并排序后的输出为:

python
[3, 9, 10, 27, 38, 43, 82]

逐步讲解

分解

  1. 初始数组为 [38, 27, 43, 3, 9, 82, 10]
  2. 第一次分解为 [38, 27, 43, 3][9, 82, 10]
  3. 继续分解,直到每个子数组只包含一个元素。

合并

  1. [38][27] 合并为 [27, 38]
  2. [43][3] 合并为 [3, 43]
  3. [27, 38][3, 43] 合并为 [3, 27, 38, 43]
  4. [9][82] 合并为 [9, 82]
  5. [10][9, 82] 合并为 [9, 10, 82]
  6. 最后将 [3, 27, 38, 43][9, 10, 82] 合并为 [3, 9, 10, 27, 38, 43, 82]

实际应用场景

归并排序在实际中有广泛的应用,特别是在需要稳定排序和大数据量排序的场景中。例如:

  • 数据库排序:在数据库中,归并排序常用于对大量数据进行排序。
  • 外部排序:当数据量太大无法全部加载到内存时,归并排序是一种常用的外部排序算法。
  • 链表排序:归并排序是链表排序的首选算法,因为它在链表上的时间复杂度仍然是 O(n log n)。

总结

归并排序是一种高效且稳定的排序算法,适用于各种需要排序的场景。它的时间复杂度为 O(n log n),在处理大数据量时表现优异。通过分治法的思想,归并排序将问题分解成更小的子问题,递归地解决这些子问题,然后将结果合并成最终的解。

附加资源与练习

  • 练习:尝试实现归并排序的非递归版本。
  • 资源:阅读更多关于分治法的资料,了解其他使用分治法的算法,如快速排序和二分查找。
提示

归并排序的稳定性使其在处理需要保持相对顺序的数据时非常有用。例如,在排序包含相同元素的数组时,归并排序可以保持这些元素的原始顺序。

警告

归并排序的空间复杂度为 O(n),因为它需要额外的空间来存储合并后的数组。在处理内存受限的环境时,需要注意这一点。