我编写了一个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
答案 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