【python & 归并排序算法】

算法基本原理思想

  • 归并排序体现分而治之的分治策略

-归并排序是递归算法,思路是将数据表持续分裂为两半,对两半分别进行归并排序

  • 递归的基本结束条件是:数据表仅有1个数据项,自然是排好序的;
  • 缩小规模:将数据表分裂为相等的两半,规模减为原来的二分之一;
  • 调用自身:将两半分别调用自身排序,然后将分别排好序的两半进行归并,得到排好序的数据表
  • 算法流程示意图:

在这里插入图片描述

简单排序代码示例

  • 基本传统的代码:



'''
@ time :2021年10月22日
@ author : wupke
@ description: 归并排序算法
'''
import time

# # #    
start1 = time.clock()

def mergeSort(alist):
    # print("splitting",alist)
    # 包含了递归的基本结束条件:代码中已经表示了,当len(list)<=1 ,就会退出程序
    if len(alist)>1:
        mid = len(alist)//2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]
        # 递归调用
        mergeSort(lefthalf)
        mergeSort(righthalf)

        # 拉链式交错把左右半部分从小到大顺序归并到结果列表中
        i = j = k =0
        while i<len(lefthalf) and j < len(righthalf):
            if lefthalf[i]<righthalf[j]:
                alist[k]=alist[i]
                i = i+1
            else:
                alist[k]=righthalf[j]
                j = j+1
            k = k+1
        #归并左半部分剩余项
        while i<len(lefthalf):
            alist[k] = lefthalf[i]
            i=i+1
            k=k+1
        #归并右半部分剩余项
        while j<len(righthalf):
            alist[k] = righthalf[j]
            j=j+1
            k=k+1

alist = [22,33,44,55,21,31,45,76,88,54,3,5,7,2]
mergeSort(alist)
end1 = time.clock()
print("%s排序用时%s" %(alist,(end1-start1)))


  • 算法流程图:
    在这里插入图片描述

python 化的代码版本:

  • 代码
'''
@ time :2021年10月22日
@ author : wupke
@ description: 归并排序算法
'''
import time

# # #    
start1 = time.clock()
def merge_Sort(lst):
    #  递归基本结束条件
    if len(lst) <=1:
        return lst
    # 问题分解 并递归调用
    middle = len(lst)//2
    # 左半部分排好序
    left = merge_Sort(lst[:middle]) 
    # 右半部分排好序
    right = merge_Sort(lst[middle:])

    # 合并左右部分 ,完成排序
    merged  = []
    while left and right:
        if left[0] <= right[0]:
            merged.append(left.pop(0))
        else:
            merged.append(right.pop(0))
    #归并左右余项
    merged.extend(right if right else left)
    return merged

alist = [22,33,44,55,21,31,45,76,88,54,3,5,7,2]
merge_Sort(alist)
end1 = time.clock()
print("%s排序用时%s" %(alist,(end1-start1)))


复杂度分析

  • 归并排序分为两个过程来分析:分裂和归并
  • 分裂的过程,借鉴二分查找中的分析结果,是对数复杂度,时间复杂度为O(log n)
  • 归并的过程,相对于分裂的每个部分,其所有数据项都会被比较和放置一次,所以是线性复杂度,其时间复杂度是O(n)
  • 综合考虑,每次分裂的部分都进行一次0(n)的数据项归并,总的时间复杂度是0(nlog n)
  • 最后,我们还是注意到两个切片操作为了时间复杂度分析精确起见,可以通过取消切片操作,改为传递两个分裂部分的起始点和终止点,也是没问题的,只是算法可读性稍微牺牲一点点。
  • 要注意到归并排序算法使用了额外1倍的存储空间用于归并
    这个特性在对特大数据集进行排序的时候要考虑进去

猜你喜欢

转载自blog.csdn.net/Kefenggewu_/article/details/120900088