理解Python中的合并和排序算法

时间:2012-09-20 19:51:30

标签: python algorithm

所以我试图在python中理解这个简单的合并和排序算法。这是代码:

def merge(left, right, lt):
    """Assumes left and right are sorted lists.

    lt defines an ordering on the elements of the lists.
    Returns a new sorted(by lt) list containing the same elements
    as (left + right) would contain.

    """
    result = []
    i,j = 0, 0
    while i < len(left) and j < len(right):
       if lt(left[i], right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
        while (i < len(left)):
            result.append(left[i])
            i += 1
        while (j < len(right)):
            result.append(right[j])
            j += 1
    return result

def sort(L, lt = lambda x,y: x < y):
    """Returns a new sorted list containing the same elements as L"""
    if len(L) < 2:
        return L[:]
    else:
        middle = int(len(L)/2)
        left = sort(L[:middle], lt)
        right = sort(L[middle:], lt)
        print left, right
        return merge(left, right, lt)

我得到它正在尝试做的事情,并且我理解合并函数中的所有代码并且对sort函数有基本的了解。

我不明白的是sort函数的“else”部分是如何工作的。它似乎保持递归调用sort函数,为左右变量分配越来越小的拆分列表。但是因为它在每次调用递归函数时都将新列表分配给“left”和“right”,所以最终结果不会是左右的最小版本吗?

合并函数如何在递归之外,知道它需要合并创建的每个拆分列表?

2 个答案:

答案 0 :(得分:6)

sort()是递归的,但是达到了一定程度。一旦if的长度小于2(或等于1),list条件将中断递归:

if len(L) < 2:

Wikipedia实际上有一个很好的动画,显示了Merge排序的工作原理:

enter image description here

基本上,merge()组合了两个排序列表,并返回一个排序列表。 sort()递归地将列表分成对,并一次一步地对这些对进行排序,合并两个已排序的对,以在递归的每一步形成一个更大的排序列表。只是看动画。解释比我好。

答案 1 :(得分:3)

你应该画出调用堆栈,看看会发生什么。

else子句再次调用sort函数时,该函数不会从那里退出。每个电话都以return个陈述之一结束。

所以你是正确的,最初对sort的调用是在越来越小的列表中传递,但是一旦长度变得小于2,'sort'就会返回列表本身。然后,调用将返回到原来的位置并调用print,最后调用merge

尝试使用小列表并记下每个电话。你会看到最终merge会被调整到已经排序的小列表上(因为它们很短)。