归并排序(递归)

1.概念

归并排序法是针对已经排好的两个或两个以上的数列,通过合并的方式,将其组合成一个有序的大数列。使用归并排序法为一个数列排序时,首先将无序的数列分成若干小份。分若干分的规则就是不断把每段长度除以2(对半分),直到分到不能再分为止,然后对最小分进行排序,最后再逐步合并成一个有序的大数列。

2.代码

def merge_sort(data):
    if len(data)<=1:
        return data
    # 递归终止条件,即长度小于等于1时,不再进行分割直接返回

    mid=len(data)//2
    left=data[:mid]
    right=data[mid:]
    left=merge_sort(left)
    right=merge_sort(right)
    # 运用递归对两部分进行分割,并执行排序操作

    result=[]
    # 创建一个空列表 result 用于存储排序结果。

    while left and right:
    # 当 left 和 right 都不为空时,比较它们的第一个元素。

        if left[0]<=right[0]:
            result.append(left.pop(0))
    # 如果 left 的第一个元素小于或等于 right 的第一个元素,
    # 将 left 的第一个元素添加到 result 中,并使用 pop(0) 从 left 中移除该元素。
        else:
            result.append((right.pop(0)))
    # 否则,将 right 的第一个元素添加到 result 中,并使用 pop(0) 从 right 中移除该元素。

    if left:
        result+=left
    # 如果 left 不为空,将 left 中的剩余元素添加到 result 中。
    if right:
        result+=right
    # 如果 right 不为空,将 right 中的剩余元素添加到 result 中。
    return result

data=[34,45,33,5,24,66,9,2]
print(merge_sort(data))

3.过程解释

初始:data = [34, 45, 33, 5, 24, 66, 9, 2]
mid = 4,left = [34, 45, 33, 5],right = [24, 66, 9, 2]。
    递归调用:
    merge_sort([34, 45, 33, 5]):
    mid = 2,left = [34, 45],right = [33, 5]。
        递归调用:
        merge_sort([34, 45]):
        mid = 1,left = [34],right = [45]。
        排序后:[34] 和 [45] 合并为 [34, 45]。
        merge_sort([33, 5]):
        mid = 1,left = [33],right = [5]。
        排序后:[5, 33]。
        合并 [34, 45] 和 [5, 33]:
比较 34 和 5,添加 5 到 result,result = [5]。
比较 34 和 33,添加 33 到 result,result = [5, 33]。
剩下 34 和 45,添加 34 和 45 到 result,result = [5, 33, 34, 45]。

merge_sort([24, 66, 9, 2]):
mid = 2,left = [24, 66],right = [9, 2]。
    递归调用:
    merge_sort([24, 66]):
    mid = 1,left = [24],right = [66]。
    排序后:[24, 66]。
    merge_sort([9, 2]):
    mid = 1,left = [9],right = [2]。
    排序后:[2, 9]。
    合并 [24, 66] 和 [2, 9]:
    比较 24 和 2,添加 2 到 result,result = [2]。
    比较 24 和 9,添加 9 到 result,result = [2, 9]。
    剩下 24 和 66,添加 24 和 66 到 result,result = [2, 9, 24, 66]。

合并:
合并 [5, 33, 34, 45] 和 [2, 9, 24, 66]:
比较 5 和 2,添加 2 到 result,result = [2]。
比较 5 和 9,添加 5 到 result,result = [2, 5]。
比较 33 和 9,添加 9 到 result,result = [2, 5, 9]。
比较 33 和 24,添加 24 到 result,result = [2, 5, 9, 24]。
比较 33 和 66,添加 33 到 result,result = [2, 5, 9, 24, 33]。
剩下 34 和 66,添加 34 到 result,result = [2, 5, 9, 24, 33, 34]。
剩下 45 和 66,添加 45 到 result,result = [2,5,9,24,33,34,45]。
剩下 66,添加 66 到 result,result = [2, 5, 9, 24, 33, 34, 45, 66]。
# 为了更容易看出过程,可以在代码执行过程中
# 输出每一次的结果并在结果处做上标记
def merge_sort(data):
    if len(data)<=1:
        return data
    mid=len(data)//2
    left=data[:mid]
    right=data[mid:]
    left=merge_sort(left)
    right=merge_sort(right)
    result=[]
    while left and right:
        if left[0]<=right[0]:
            result.append(left.pop(0))
            print(result)
            print("-"*20)
        else:
            result.append((right.pop(0)))
            print(result)
            print("=" * 20)
    if left:
        result+=left
        print(result)
        print('*'*20)
    if right:
        result+=right
        print(result)
        print('^'*20)
    return result
data=[34,45,33,5,24,66,9,2]
merge_sort(data)

# 输出结果:
# [34]
# --------------------
# [34, 45]
# ^^^^^^^^^^^^^^^^^^^^
# [5]
# ====================
# [5, 33]
# ********************
# [5]
# ====================
# [5, 33]
# ====================
# [5, 33, 34, 45]
# ********************
# [24]
# --------------------
# [24, 66]
# ^^^^^^^^^^^^^^^^^^^^
# [2]
# ====================
# [2, 9]
# ********************
# [2]
# ====================
# [2, 9]
# ====================
# [2, 9, 24, 66]
# ********************
# [2]
# ====================
# [2, 5]
# --------------------
# [2, 5, 9]
# ====================
# [2, 5, 9, 24]
# ====================
# [2, 5, 9, 24, 33]
# --------------------
# [2, 5, 9, 24, 33, 34]
# --------------------
# [2, 5, 9, 24, 33, 34, 45]
# --------------------
# [2, 5, 9, 24, 33, 34, 45, 66]
# ^^^^^^^^^^^^^^^^^^^^

### 归并排序递归实现详解 归并排序是一种基于分治策略的有效排序算法,其核心思想是通过不断分割数组直到每个子数组仅剩下一个元素,随后逐步合并这些已排序的小数组形成最终的大数组。这种方法能够保证即使面对无序程度不同的输入序列也能维持稳定的 \(O(n \log n)\) 时间复杂度[^3]。 #### 递归版本的归并排序逻辑分解 1. **基础条件判断**: 若当前处理的数组长度小于等于1,则无需继续划分,直接返回原数组。 2. **分裂过程**: 找到中间索引位置 `mid` 并以此为界将原始数组切分成左半部分与右半部分。 3. **递归调用**: 对左右两部分各自再次执行相同的归并排序流程直至达到最小子单元级别。 4. **合并阶段**: 利用辅助函数完成两个已经排好序的部分之间的融合工作,确保整体有序性得以保持。 下面给出完整的Python代码示例: ```python def merge_sort_recursive(arr): """递归方式实现归并排序""" # 基础情况:当数组长度不大于1时停止递归 if len(arr) <= 1: return arr # 计算中心点进行分割 mid = len(arr) // 2 left_half = arr[:mid] right_half = arr[mid:] # 对左右两侧分别递归调用merge_sort_recursive sorted_left = merge_sort_recursive(left_half) sorted_right = merge_sort_recursive(right_half) # 合并两个已排序好的列表 return _merge(sorted_left, sorted_right) def _merge(left, right): """ 辅助函数用于合并两个有序列表left和right成为一个更大的有序列表 :param left: 左侧有序列表 :param right: 右侧有序列表 :return: 合并后的单个有序列表 """ result = [] i = j = 0 # 循环对比两边最小项依次填入result中 while i < len(left) and j < len(right): if left[i] <= right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 # 处理可能存在的剩余元素 result.extend(left[i:]) result.extend(right[j:]) return result if __name__ == "__main__": test_array = [29, 7, 70, 42, 90, 3, 87, 8, 30, 5] print("Original array:", test_array) sorted_array = merge_sort_recursive(test_array.copy()) print("Sorted array :", sorted_array) ``` 上述程序展示了如何利用递归来构建归并排序的核心机制,并且包含了详细的注释以便理解各个组成部分的功能作用[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值