返回

归并排序:你必须知道的稳定排序算法

闲谈

归并排序,作为一种稳定的排序算法,因其分治思想和高效性能而在计算机科学领域备受推崇。在这篇文章中,我们将深入剖析归并排序的思想、步骤、复杂度分析以及代码实现,帮助您全面掌握这种优秀的排序算法。

算法思想

归并排序的思想可以概括为“分而治之”。其主要步骤如下:

  1. 将原数组一分为二,直至每个子数组中仅含一个元素。
  2. 对每个子数组进行递归排序。
  3. 将排序后的子数组合并成一个有序数组。

通过将数组不断划分为更小的子数组,递归排序,然后合并这些有序的子数组,最终得到一个有序的完整数组。

步骤

  1. 将原数组一分为二,若无法继续分割,则递归结束。
  2. 对两个子数组分别进行归并排序。
  3. 将排序后的两个子数组合并成一个有序数组。
  4. 重复步骤 1 至 3,直至所有元素有序排列。

复杂度分析

归并排序的时间复杂度主要取决于合并过程。合并过程的时间复杂度为 O(n),其中 n 为数组的长度。由于归并排序需要递归划分数组,因此其时间复杂度为 O(n log n)。归并排序的空间复杂度为 O(n),因为需要额外的空间来存储临时数组。

代码实现

def merge_sort(array):
    """归并排序算法实现

    :param array: 待排序数组
    :type array: list
    :return: 排序后的数组
    :rtype: list
    """

    if len(array) <= 1:
        return array

    # 将数组一分为二
    mid = len(array) // 2
    left_array = array[:mid]
    right_array = array[mid:]

    # 递归对子数组进行排序
    left_array = merge_sort(left_array)
    right_array = merge_sort(right_array)

    # 合并两个有序子数组
    return merge(left_array, right_array)


def merge(left_array, right_array):
    """合并两个有序数组

    :param left_array: 有序左数组
    :type left_array: list
    :param right_array: 有序右数组
    :type right_array: list
    :return: 合并后的有序数组
    :rtype: list
    """

    merged_array = []
    left_index = 0
    right_index = 0

    # 合并两个数组,直至其中一个数组为空
    while left_index < len(left_array) and right_index < len(right_array):
        if left_array[left_index] <= right_array[right_index]:
            merged_array.append(left_array[left_index])
            left_index += 1
        else:
            merged_array.append(right_array[right_index])
            right_index += 1

    # 将剩余元素添加到合并后的数组
    merged_array.extend(left_array[left_index:])
    merged_array.extend(right_array[right_index:])

    return merged_array

# 测试归并排序
array = [5, 2, 8, 3, 1, 9, 4, 7, 6]
sorted_array = merge_sort(array)
print(sorted_array)

应用场景

归并排序广泛应用于各种领域,包括:

  • 数据排序
  • 合并多个有序数组
  • 查找中位数
  • 查找逆序对数量
  • 计算最长公共子序列

归并排序以其稳定性、较低的时间复杂度和易于实现的特点,成为众多排序算法中不可忽视的重要一员。