[python] 分治法实现归并排序算法

                                             分治法实现归并排序

 

分治法简介:

          分治法从字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或者更多相同或者相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。归并排序算法也是简历在分治法的操作上实现的算法,归并排序将一个序列分成多个子序列,将所有子序列有序,再将有序的子序列合并,得到排好序的序列。

 

归并排序基本原理:

 (1)  递归将问题分解,将序列元素大于等于3个的时候,将数组分为两个更小的数组并继续判断元素个数进行划分。

 (2)  解决小规模的问题,如序列中只有一个或者两个元素的时候,将小规模问题进行排序。

 (3)  依次将小规模的问题进行合并,每次得到比小规模问题大一倍的规模的有序序列。

 (4)  最后规模扩大到原问题的规模时,得到的序列便是排好序的有序序列。

归并排序关键代码思想:

 (1) 归并过程的实现,定义一个归并函数并且传入三个参数,传入序列,左端点下标和右端点下标。对序列进行平均划分,将两个序列中较小元素的值先进行比较存放到一个临时序列,再将未比较的值进行依次传入临时序列,最后将临时列表重新赋给传入参数列表。

 (2)  分治操作实现,定义一个分治函数,传入三个参数,传入序列,左端点以及右端点下标。对序列长度进行判断,如果序列长度大于等于1时,继续进行划分,如果序列长度小于1,就停止划分,最后再实现由局部到整体的合并。

 (3)  python3.6版本中的输入默认为字符串,因此输入序列采用split()函数对输入的字符串以“ ”为界进行分离取值,再将其存放到一个数组中。注意存放到数组中时,每个元素都还是字符串,利用强制转换将每个元素转换为int型,再将其append到数组中。

(4) 计算程序运行时间,导入python自带的time模块,采用模块中的clock函数,在归并排序前后分别调用clock函数记录时间,最后两个时间值作差值,得到归并排序算法实现的运行时间。

归并具体实例分析:

假如给定序列5 3 4 6 8 1 7 9,利用上述思想对序列进行排序。

(1)先将序列进行划分为细小的模块

          首先原始数列传入:5 3 4 6 8 1 7 9,第一组合并还未进行。

          第一次划分:5 3 4 6 || 8 1 7 9,第二组合并还未进行。

          第二次划分:5 3 || 4 6 || 8 1 || 7 9,第三组合并还未进行。

(2) 因为每组元素序列个数已经小于等于2,因此开始进行合并操作

          进行第三组合并:5 3 || 4 6 || 8 1 || 7 9 ——> 3 5 || 4 6 || 1 8 || 7 9

          进行第二组合并:3 5  4 6 || 1 8  7 9 ——> 3 4 5 6 || 1 7 8 9

          进行第一组合并: 3 4 5 6 || 1 7 8 9 ——> 1 3 4 5 6 7 8 9

   最终得到的序列便为已经排好序的有序序列。

归并排序代码的具体实现:

import time

def hebin(arr,left,right):
    mid = int((right - left)/2 + left)
    temp = []
    i = left
    j = mid + 1
    while i<mid+1 and j<right+1:
        if arr[i]>arr[j]:
            temp.append(arr[j])
            j+=1
        else:
            temp.append(arr[i])
            i+=1
    while i<mid+1:
        temp.append(arr[i])
        i+=1
    while j<right+1:
        temp.append(arr[j])
        j+=1
    mm = 0
    for tt in range(left,right+1):
        arr[tt] = temp[mm]
        mm+=1

def fenzhi(arr,left,right):
    if right - left<1:
        return 0
    else:
        mid = int((right - left)/2 + left)
        fenzhi(arr,left,mid)
        fenzhi(arr,mid+1,right)
        hebin(arr,left,right)

def main():
    a=[]
    t = input().split(" ")
    time1 = time.clock()
    for tt in t:
        a.append(int(tt))
    left = 0
    right = len(a) - 1
    fenzhi(a,left,right)
    time2 = time.clock()
    for n in a:
        print(n ,end = " ")
    print("\n程序运行时间:%f"%(time2 - time1))
    
if __name__ == '__main__':
    main()

 

测试记录:

 

注意事项:

进行输入序列操作时,输入的序列元素之间有且只能有一个空格隔开,并且在序列末尾不能含有空格,否则程序会报错。

               

猜你喜欢

转载自blog.csdn.net/qq_40102757/article/details/81585831