zoukankan      html  css  js  c++  java
  • 归并排序-Python

    归并排序也是只听说,没看过算法的代码也没写过,昨天晚上看了下归并排序的思想,似乎是一个我可以驾驭的递归,于是就准备自己手写

    本文主要记录一下我写归并的历程,博友可以直接跳到最终版

    先写上我的思路(写递归最重要的就是思路,以前总喜欢画栈的结构图来构思,现在才发现这只是写递归的必备基础,而非方法,所以我这次举一个简单的列表,直接根据数据流动(网站开发的习惯)来确定思路,顺便还能考虑下所有特殊情况)

    再附上我的代码(写了几个小时候我还是崩溃了)

     1 def merge_sort(clist,low,high):
     2     mid = (high + low + 1) // 2
     3     if len(clist)>1:          # 进行拆分
     4         glist = []
     5         for item in range(low, high+1):
     6             glist.append(clist[item])
     7         left_list = merge_sort(glist, low, mid - 1)
     8         right_list = merge_sort(glist, mid, high)
     9         # 合并
    10         return merges(left_list, right_list)
    11     else:
    12         return clist
    13 
    29 # 将俩个等长有序的列表合并=>插入排序好些,还是有些亏,浪费了第二个列表等长有序的属性了
    30 def merges(firstList,secondList):
    31     length=len(firstList)
    32     reList=[]
    33     j=0
    34     i=0
    35     while i<length or j<length:
    36         if i>=length:
    37             reList.append(secondList[j])
    38             j+=1
    39         elif j>=length:
    40             reList.append(firstList[i])
    41             i+=1
    42         else:
    43             if firstList[i]<secondList[j]:
    44                 reList.append(firstList[i])
    45                 i+=1
    46             else:
    47                 reList.append(secondList[j])
    48                 j+=1
    49     return reList
    50 
    51 if __name__=="__main__":
    52     cclist=[54,26,93 ,17,77,31,44,55,20]  #,17,77,31,44,55,56
    53     print(merge_sort(cclist,0,len(cclist)-1))
    54  
    57     # ===>崩溃

    写到这里,debug时发现high到最后会为-1,显示是不对的,但low,high,mid这三个参数怎么调,glist拆分为左右俩个列表时总是有索引越界的问题

    附上改正后的代码=》申请俩个独立的列表,在某种程度上说是low,high与mid的解耦,当时的想法是:low固定为0后,只要合理设置high的值就行了,同时mid的值也无需分情况讨论,但是多申请一个列表会浪费空间吗?

    答案是不会的,因为反正需要存储clist的所有元素,用俩个列表只是分两次存储罢了。

    改后的代码(还是有一些瑕疵,因为申请两个列表完全可以通过且列表切片得到,merges不需要改变)

    def merge_sort(clist):
        n=len(clist)
        if n>1:
            mid = n// 2
            l_list = []
            r_list=[]
            for item in range(0, n):
                if item<mid:
                    l_list.append(clist[item])
                else:
                    r_list.append(clist[item])
            left_list = merge_sort(l_list)
            right_list = merge_sort(r_list)
            # 合并
            return merges(left_list, right_list)
        else:
            return clist

    最后附上最终版(用了分片明显感觉就很舒服)

    def mergeSort(clist):
        """"归并排序"""
        n=len(clist)
        if n<=1:
            return clist
        mid=n//2
        left_list=mergeSort(clist[:mid])  # 可以通过切片而非循环来确认左右列表
        right_list = mergeSort(clist[mid:])  
        return merges(left_list,right_list)

    回顾整个过程:有个错误一直没有深究,导致我如此崩溃,我曾经想过用俩个列表拆分传入的clist,但是莫名其妙地就感觉这样会浪费空间,感觉通过一个列表和low,high两个索引同样可以实现划分左右列表的目的,但其实这样需要考虑很多情况,考虑到最后就崩溃了。而如果我深入思考一步,不是下意识地认为,就能很愉快地完成归并了。

    心之所愿,永不相忘
  • 相关阅读:
    openssl生成CA和服务器SSL证书
    Windows编译安装openssl
    yasea浅析
    谈落后时的自卑感(三)
    更新Jekyll
    码云博客
    谈落后时的自卑感(二)
    谈落后时的自卑感(一)
    怎么才能更好的帮助企业进行数据挖掘
    云计算将来会面临什么样的安全威胁?
  • 原文地址:https://www.cnblogs.com/zgll/p/11158444.html
Copyright © 2011-2022 走看看