📜  合并排序算法(1)

📅  最后修改于: 2023-12-03 15:07:28.125000             🧑  作者: Mango

合并排序算法

合并排序算法是一种基于分治策略的经典排序算法。它将一个待排序的数组,划分为两个子数组,通过递归地对子数组进行排序,最后将两个有序子数组进行合并得到完全有序的数组。

算法思路
  1. 将待排序数组划分为两个子数组,分别对两个子数组递归地应用合并排序算法,得到两个有序子数组;
  2. 将两个有序子数组合并为一个完全有序的数组。
算法实现
递归实现
def merge_sort(arr):
    # 递归边界,数组长度小于等于1时
    if len(arr) <= 1:
        return arr
    
    # 划分为两个子数组
    mid = len(arr) // 2
    left_arr = arr[:mid]
    right_arr = arr[mid:]
    
    # 递归地对子数组应用合并排序算法
    left_arr_sorted = merge_sort(left_arr)
    right_arr_sorted = merge_sort(right_arr)
    
    # 将两个有序子数组合并为一个完全有序的数组
    merged_arr = []
    while left_arr_sorted and right_arr_sorted:
        if left_arr_sorted[0] <= right_arr_sorted[0]:
            merged_arr.append(left_arr_sorted.pop(0))
        else:
            merged_arr.append(right_arr_sorted.pop(0))
    merged_arr.extend(left_arr_sorted)
    merged_arr.extend(right_arr_sorted)
    return merged_arr
迭代实现
def merge_sort(arr):
    size = 1
    n = len(arr)
    while size < n:
        left = 0
        while left < n:
            mid = left + size - 1
            right = min(left + 2*size - 1, n-1)

            # merge
            merged_arr = []
            i = left
            j = mid + 1
            while i <= mid and j <= right:
                if arr[i] <= arr[j]:
                    merged_arr.append(arr[i])
                    i += 1
                else:
                    merged_arr.append(arr[j])
                    j += 1
            while i <= mid:
                merged_arr.append(arr[i])
                i += 1
            while j <= right:
                merged_arr.append(arr[j])
                j += 1
            for k in range(left, right+1):
                arr[k] = merged_arr[k-left]

            left += 2*size

        size *= 2
    return arr
算法分析
  • 时间复杂度:O(n * log n),其中 n 为待排序数组的长度,因为每次将数组划分成两个子数组,需要 O(log n) 次,每次合并两个子数组需要 O(n) 的时间复杂度。
  • 空间复杂度:O(n),需要额外的空间保存各级子数组排序后的结果。
  • 稳定性:稳定,因为在合并两个有序子数组的过程中,如果遇到相等的元素,先处理左侧的元素,保证排序的稳定性。