O(n)堆化算法

时间:2014-04-16 01:31:44

标签: python algorithm heap bottom-up

我编写了一个O(n)算法' heapifying' Python中的列表。我无法理解它为什么不起作用。

def func(l):
    size=len(l)
    for root in range((size//2)-1,-1,-1):
        child = 2*root+1 #parent of child is target
        while(child<size):
            #l[child] should be smaller sibling
            if child<size-1 and l[child]>l[child+1]:
                child+=1
            #can we put l[root] in l[child//2]?
            if l[root]<=l[child]:
                break #yes
            #no
            l[child//2]=l[child]#move child up
            child=2*child+1#move down a level
        l[child//2]=l[root]
    return l

2 个答案:

答案 0 :(得分:2)

您的功能有两个问题。

第一个很容易掌握。您使用错误的计算来查找child索引的父级。而不是child // 2,您应该使用(child - 1) // 2。这导致你将一些值转移到错误的位置。

第二个问题有点微妙。如果l[root]大于其中一个子项,则您当前正在使用该子项覆盖它,因此当您尝试将其插入到列表中稍后的其他位置时,原始值将不再可用。您可能应将l[root]保存在for循环的顶部,然后在代码中稍后检查l[root]的任何时候使用保存的值(if里面的while def func(l): size=len(l) for root in range((size//2)-1,-1,-1): root_val = l[root] # save root value child = 2*root+1 while(child<size): if child<size-1 and l[child]>l[child+1]: child+=1 if root_val<=l[child]: # compare against saved root value break l[(child-1)//2]=l[child] # find child's parent's index correctly child=2*child+1 l[(child-1)//2]=root_val # here too, and assign saved root value return l 循环以及结束后的最终分配。

这是代码的固定版本,注释指出我所做的更改:

{{1}}

答案 1 :(得分:0)

上面的好解释,这是一个小修改版本:

 # heapify in place
 def heapify(A):
    # write your code here
    for root in xrange(len(A)//2-1, -1, -1):
        rootVal = A[root]
        child = 2*root+1
        while child < len(A):
            if child+1 < len(A) and A[child] > A[child+1]:
                child += 1
            if rootVal <= A[child]:
                break
            A[child], A[(child-1)//2] = A[(child-1)//2], A[child]
            child = child *2 + 1