排序算法专题之归并排序

Posted Python算法之旅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法专题之归并排序相关的知识,希望对你有一定的参考价值。

说在前面

归并排序是分治算法的典型运用,其中先分治,再合并的思路真是美妙至极。

    归并排序算法的基本操作是合并两个已排序的表,这只需要线性的时间,不足之处是需要分配一个临时数组来暂存数据。

    归并排序算法可以用递归的形式实现,形式简洁易懂。如果N=1,则只有一个元素需要排序,我们可以什么都不做;否则,递归地将前半部分数据和后半部分数据各自归并排序,然后合并这两个部分。

    归并排序算法也可以用非递归的形式实现,稍微难理解一点。它刚好是递归分治算法的逆向思维形式,在使用递归分治算法时,程序员只需考虑将一个大问题分成若干个形式相同的小问题,和解的边界条件,具体如何解决这些小问题是由计算机自动完成的;而非递归形式要求程序员从最基本的情况出发,即从解决小问题出发,一步步扩展到大问题。


“Python算法之旅”微信群等着你
排序算法专题之归并排序
排序算法专题之归并排序
排序算法专题之归并排序
排序算法专题之归并排序

扫码加入“Python算法之旅”微信群,和斌哥面对面交流,更多资料和更有趣的话题等你一起来分享。

排序算法专题之归并排序

归并排序算法(填空版)

1.  合并有序列表

例1.将有序列表a和b(均为升序列表)合并成一个新的有序列表c

例如,a = [1, 3, 4, 6, 8],b = [2, 5, 7],

合并后的列表c =  [1, 2, 3, 4, 5, 6, 7, 8]。

函数名:merge(a, b)

参数表:a -- 升序列表。b -- 升序列表。

返回值:合并后的升序列表。

def merge(a, b):

    c = []

    i = j = 0

    while i < len(a) and j < len(b):

        if a[i] < b[j]:

            c.append(①                  )

            i += 1

        else:

            c.append(b[j])

            j += 1

    c.extend(a[i:])

    ②                        

return c


2.  非原地归并排序

例2.归并排序是分治算法的典型运用,其中先分治,再合并的思路真是美妙至极。

归并排序算法的基本操作是合并两个已排序的表,这只需要线性的时间,不足之处是需要分配一个临时数组来暂存数据。归并排序算法可以用递归的形式实现,形式简洁易懂。

如果N=1,则只有一个元素需要排序,我们可以什么都不做;否则,递归地将前半部分数据和后半部分数据各自归并排序,然后合并这两个部分。

函数名:merge_sort(a)

参数表:a -- 待排序列表。

返回值:升序排序后的新列表。

def merge_sort(a):

    if len(a) <= 1:

        return ①                     

    else:

        m = len(a) // 2 #将列表尽量平分成两部分    

        left = ②                       #对左段列表归并排序

        right = merge_sort(a[m:])#对右段列表归并排序

        return merge(left, right) #合并两段有序列表


3.  改进归并排序(原地归并排序)

例3. 在归并排序函数内嵌套定义归并排序子函数和合并序列子程序,不必另外分配空间。

函数名:merge_sort_2(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象进行升序排序。

def merge_sort_2(a):

    #嵌套定义归并排序子函数

    def m_sort(left, right):

        if left < right:

            mid = (left + right) // 2

            m_sort(left, mid)#对左段列表归并排序

            m_sort(①                     )#对右段列表归并排序

            merge(left, mid, right) #合并两段有序列表

   

    #嵌套定义子函数,将a[left:mid+1]和a[mid+1:right+1]合并成有序序列

    def merge(left, mid, right):

        c = []

        i, j = left, mid+1

        while i <= mid and j <= right:

            if a[i] < a[j]:

                c.append(a[i])

                i += 1

            else:

                c.append(a[j])

                j += 1

        c.extend(a[i:mid+1])

        ②                       

        for i, e in enumerate(c, left): #将有序序列复制回列表a

            ③                       


    m_sort(0, len(a)-1) #调用归并排序子函数
归并排序算法(完整版)

1.  合并有序列表

例1.将有序列表a和b(均为升序列表)合并成一个新的有序列表c

例如,a = [1, 3, 4, 6, 8],b = [2, 5, 7],

合并后的列表c =  [1, 2, 3, 4, 5, 6, 7, 8]。

函数名:merge(a, b)

参数表:a -- 升序列表。b -- 升序列表。

返回值:合并后的升序列表。

def merge(a, b):

    c = []

    i = j = 0

    while i < len(a) and j < len(b):

        if a[i] < b[j]:

            c.append(a[i])

            i += 1

        else:

            c.append(b[j])

            j += 1

    c.extend(a[i:])

    c.extend(b[j:])

return c


2.  非原地归并排序

例2.归并排序是分治算法的典型运用,其中先分治,再合并的思路真是美妙至极。

归并排序算法的基本操作是合并两个已排序的表,这只需要线性的时间,不足之处是需要分配一个临时数组来暂存数据。归并排序算法可以用递归的形式实现,形式简洁易懂。

如果N=1,则只有一个元素需要排序,我们可以什么都不做;否则,递归地将前半部分数据和后半部分数据各自归并排序,然后合并这两个部分。

函数名:merge_sort(a)

参数表:a -- 待排序列表。

返回值:升序排序后的新列表。

def merge_sort(a):

    if len(a) <= 1:

        return a

    else:

        m = len(a) // 2    #将列表尽量平分成两部分 

        left = merge_sort(a[:m])#对左段列表归并排序

        right = merge_sort(a[m:])#对右段列表归并排序

        return merge(left, right) #合并两段有序列表


3.  改进归并排序(原地归并排序)

例3. 在归并排序函数内嵌套定义归并排序子函数和合并序列子程序,不必另外分配空间。

函数名:merge_sort_2(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象进行升序排序。

def merge_sort_2(a):

    #嵌套定义归并排序子函数

    def m_sort(left, right):

        if left < right:

            mid = (left + right) // 2

            m_sort(left, mid)#对左段列表归并排序

            m_sort(mid+1, right)#对右段列表归并排序

            merge(left, mid, right) #合并两段有序列表

   

    #嵌套定义子函数,将a[left:mid+1]和a[mid+1:right+1]合并成有序序列

    def merge(left, mid, right):

        c = []

        i, j = left, mid+1

        while i <= mid and j <= right:

            if a[i] < a[j]:

                c.append(a[i])

                i += 1

            else:

                c.append(a[j])

                j += 1

        c.extend(a[i:mid+1])

        c.extend(a[j:right+1])

        for i, e in enumerate(c, left): #将有序序列复制回列表a

            a[i] = e


    m_sort(0, len(a)-1) #调用归并排序子函数
写在后面

Python排序算法系列文章是我在阅读了大量算法专著以后,尝试用浅陋的语言把自己的理解表达出来。由于本人水平有限,表述中难免出现疏漏甚至错误之处,敬请谅解。

无论是赞同还是反对我的看法,都请你给我留言。如果你有新的想法,千万不要憋在心里,请发出来大家一起讨论。让我们相互学习,共同进步!


需要本文word版的,可以加入“选考VB算法解析”知识星球参与讨论和下载文件,“选考VB算法解析”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。

我们专注选考VB算法,感兴趣就一起来!



相关优秀文章:


以上是关于排序算法专题之归并排序的主要内容,如果未能解决你的问题,请参考以下文章

排序算法专题之选择排序

排序算法专题:快排和归并排序

排序专题-插入排序

排序算法专题之希尔排序

排序算法专题之快速排序

排序算法专题之桶排序