k方式合并排序分而治之

时间:2014-04-05 12:40:55

标签: python-3.x

from math import ceil
def merge(all_lst):
    sorted_lst = []
    while all_lst:
        min_value,index = all_lst[0][0],0
        for lst in all_lst:
            if lst[0]<min_value:
                min_value = lst[0]
                index = all_lst.index(lst)
        sorted_lst.append(min_value)
        all_lst[index].pop(0)
        if not all_lst[index]:
            all_lst.remove(all_lst[index])     
    return sorted_lst


def merge_sort(lst, k):
    def split(lst):
        split_lst = []
        j = ceil(len(lst)/k) if len(lst)>=k else 1
        for i in range(0,len(lst),j):
            split_lst.append(lst[i:i+j])
        return split_lst
    lst=split(lst)
    if len(lst[0])==1:
        return lst
    else:
        for i in range(len(lst)):
            lst[i]=merge(merge_sort(lst[i],k))
        return merge(lst)

以上是我的k-way合并排序代码。基本上它的作用是通过调用 split 函数将列表拆分为k个较小的列表,直到列表中的每个子列表都是单个元素。然后,包含子列表的列表将合并为一个列表。

分割完成两次后,我的代码工作正常。 (例如[3,6,8,5,2,1,4,7] - > [3,6,8],[5,2,1],[4,7] - > [3] ,[6],[8],[5],[2],[1],[4],[7])。但是当分裂完成两次以上时(例如,[3,6,8,5,2,1,4,7] - > [3,6,8,5],[2,1,4, 7] - &gt; [3,6],[8,5],[2,1],[4,7] - &gt; [3],[6],[8],[5],[2] ,[1],[4],[7]),代码将失败。任何人都可以帮我找到我的代码中出错的地方吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

我相信你遇到的问题是merge_sort有时返回一个扁平列表,其他时候会返回一个列表列表。在所有情况下,您应该返回一个平面列表。还有一些其他的问题:你不需要split成为它自己的功能,因为你只需要它一次。

以下是您的代码的大大简化版本:

def merge_sort(lst, k):
    if len(lst) == 1: # simpler base case
        return lst

    j = ceil(len(lst)/k) # no need to check for k < len(lst) (ceil handles it)

    #split and recursively sort in one step
    lst = [merge_sort(lst[i:i+j], k) for i in range(0, len(lst), j)]

    return merge(lst) # always return a merged list (never a list of lists)