归并排序python实现

def merge(arr, left, mid, right):
    n1 = mid - left + 1
    n2 = right - mid

    L = arr[left:left + n1]
    R = arr[mid + 1:mid + 1 + n2]

    i = j = 0
    k = left

    while i < n1 and j < n2:
        if L[i] <= R[j]:
            arr[k] = L[i]
            i += 1
        else:
            arr[k] = R[j]
            j += 1
        k += 1

    while i < n1:
        arr[k] = L[i]
        i += 1
        k += 1

    while j < n2:
        arr[k] = R[j]
        j += 1
        k += 1

def mergeSort(arr, left, right):
    if left < right:
        mid = (left + (right - 1)) // 2
        mergeSort(arr, left, mid)
        mergeSort(arr, mid + 1, right)
        merge(arr, left, mid, right)

arr = [12, 11, 13, 5, 6, 7, 88, 45, 42, -5, 56, 55, 41]
n = len(arr)

mergeSort(arr, 0, n - 1)

print("Sorted array is:")
for i in range(n):
    print(arr[i], end=" ")
  1. 函数 mergeSort 接受三个参数:

    • arr:待排序的数组。
    • left:当前子数组的左边界(起始索引)。
    • right:当前子数组的右边界(结束索引)。
  2. 首先,函数检查 left 是否小于 right。这个条件用于确定是否需要继续拆分当前子数组。如果 left 大于等于 right,则说明当前子数组中只有一个元素,它已经是有序的,不需要进一步排序。

  3. 如果 left 小于 right,则计算中间索引 mid,它将用于将当前子数组分成两部分:arr[left:mid]arr[mid+1:right]

  4. 然后,递归地调用 mergeSort 函数两次:

    • 第一次调用:对左半部分 arr[left:mid] 进行排序,即 mergeSort(arr, left, mid)
    • 第二次调用:对右半部分 arr[mid+1:right] 进行排序,即 mergeSort(arr, mid+1, right)
  5. 这两次递归调用将继续将当前子数组拆分成更小的子数组,直到每个子数组包含一个或零个元素为止,因为单个元素本身是有序的。

  6. 一旦所有递归调用完成,开始合并这些子数组。这是通过调用 merge 函数来实现的,merge 函数用于将两个有序的子数组合并为一个有序的数组。

  7. 最终,当所有递归调用完成并且 merge 函数执行完毕后,整个数组 arr 将会以升序的方式排序。

  8. merge 函数:这是执行合并操作的函数。它接受四个参数:

    • arr:待排序的数组。
    • left:子数组的左边界(起始索引)。
    • mid:子数组的中间索引,用于分割子数组为左右两部分。
    • right:子数组的右边界(结束索引)。
  9. n1n2:这两个变量用于计算左子数组 L 和右子数组 R 的长度。n1 表示左子数组的长度,n2 表示右子数组的长度。

  10. LR 数组:这两个数组分别用于存储左子数组和右子数组。它们是通过切片操作从原始数组 arr 中提取的。

  11. ijk:这三个变量用于遍历和合并左子数组 L 和右子数组 R 以生成有序的结果数组。i 用于遍历 Lj 用于遍历 Rk 用于指示合并后的数组位置。

  12. while 循环:这个循环用于比较左子数组的元素 L[i] 和右子数组的元素 R[j]。如果 L[i] 小于或等于 R[j],则将 L[i] 放入原始数组 arr 中的位置 k,然后递增 ik。如果 L[i] 大于 R[j],则将 R[j] 放入原始数组 arr 中的位置 k,然后递增 jk。这个过程重复执行,直到 ij 分别达到左子数组和右子数组的末尾。

  13. 两个额外的 while 循环:这两个循环用于处理可能剩余在左子数组 L 或右子数组 R 中的元素,因为左右两部分的长度可能不相等。这些循环将剩余的元素依次放入原始数组 arr 中的位置 k

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值