首页 > 编程语言 > 详细

排序算法之归并排序及其优化

时间:2020-03-02 17:29:04      阅读:78      评论:0      收藏:0      [点我收藏+]

归并排序

思想

归并排序,顾名思义,两个有序的数组合并成一个有序的数组。只要数组的长度大于1,都可以先分为两个数组,并将这两个子数组排好序再合并。

性能

归并排序时稳定的排序算法,平均时间复杂度和最好最坏时间复杂度均为O(nlogn)。

代码

Python代码:

# 归并排序
# left为归并区域的第一个下标,right为归并区域的最后一个下标
def mergeSort(arr, left, right):
    if left >= right: return

    # 中间下标
    mid = left + right >> 1
    # 归并当前区域的左半边区域
    mergeSort(arr, left, mid)
    # 归并当前区域的右半边区域
    mergeSort(arr, mid + 1, right)
    # 合并左右两边区域并排序
    merge(arr, left, mid, right)


# 合并左右两边区域并排序
# left为左边区域的第一个下标,mid为左边区域的最后一个下标
# mid+1为右边区域的第一个下标,right为右边区域的最后一个下标
def merge(arr, left, mid, right):
    # 排序需要借助一个数组
    tmpArr = []
    i, j = left, mid + 1
    # 同时循环左右两个区域,小的数先移进tmpArr,直到其中一个区域没有数据
    while i <= mid and j <= right:
        if arr[i] <= arr[j]:
            tmpArr.append(arr[i])
            i += 1
        else:
            tmpArr.append(arr[j])
            j += 1
    # 若左边区域还有数据,则直接添加到后面
    while (i <= mid):
        tmpArr.append(arr[i])
        i += 1
    # 若右边区域还有数据,则直接添加到后面
    while (j <= right):
        tmpArr.append(arr[j])
        j += 1

    # 将合并排好序的数据复制到原数组
    for x in tmpArr:
        arr[left] = x
        left += 1

优化

我们会发现如果左右数组的数据刚好有序,那上述代码中,仍会将数据先复制到tmpArr,再复制回原数组。
只要在merge方法前加上下面的判断,就能使最好时间复杂度降为O(n):

# 右边区域的值全部比左边区域的值大时,则不需要进行合并排序
if arr[mid] <= arr[mid + 1]: return arr
# 归并排序
# left为归并区域的第一个下标,right为归并区域的最后一个下标
def mergeSort(arr, left, right):
    if left >= right: return

    # 中间下标
    mid = left + right >> 1
    # 归并当前区域的左半边区域
    mergeSort(arr, left, mid)
    # 归并当前区域的右半边区域
    mergeSort(arr, mid + 1, right)
    # 合并左右两边区域并排序
    merge(arr, left, mid, right)


# 合并左右两边区域并排序
# left为左边区域的第一个下标,mid为左边区域的最后一个下标
# mid+1为右边区域的第一个下标,right为右边区域的最后一个下标
def merge(arr, left, mid, right):
    # 右边区域的值全部比左边区域的值大时,则不需要进行合并排序
    if arr[mid] <= arr[mid + 1]: return arr

    # 排序需要借助一个数组
    tmpArr = []
    i, j = left, mid + 1
    # 同时循环左右两个区域,小的数先移进tmpArr,直到其中一个区域没有数据
    while i <= mid and j <= right:
        if arr[i] <= arr[j]:
            tmpArr.append(arr[i])
            i += 1
        else:
            tmpArr.append(arr[j])
            j += 1
    # 若左边区域还有数据,则直接添加到后面
    while (i <= mid):
        tmpArr.append(arr[i])
        i += 1
    # 若右边区域还有数据,则直接添加到后面
    while (j <= right):
        tmpArr.append(arr[j])
        j += 1

    # 将合并排好序的数据复制到原数组
    for x in tmpArr:
        arr[left] = x
        left += 1

其他排序方法:选择排序冒泡排序

排序算法之归并排序及其优化

原文:https://www.cnblogs.com/minxiang-luo/p/12392629.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!