Python heapify的O(n)算法
我正在用Python编写一个O(n)算法来“heapify”一个列表。我不明白为什么它不起作用Python heapify的O(n)算法,python,algorithm,heap,bottom-up,Python,Algorithm,Heap,Bottom Up,我正在用Python编写一个O(n)算法来“heapify”一个列表。我不明白为什么它不起作用 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
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
def func(l):
尺寸=长度(l)
对于范围((大小//2)-1,-1,-1)中的根:
child=2*root+1#子级的父级是目标
而(child您的功能有两个问题
第一个很容易掌握。您使用错误的计算来查找子索引的父索引。您应该使用(child-1)//2
,而不是子索引//2
。这导致您将一些值移到错误的位置
第二个问题有点微妙。如果l[root]
大于它的一个子项,则您当前正在用该子项覆盖它,因此当您稍后尝试将其插入列表中的另一个位置时,原始值不再可用。可能您应该保存l[root]
在for
循环的顶部,然后在当前检查代码后面的l[根]
时使用保存的值(if
在中,而循环和结束后的最终赋值
下面是代码的固定版本,并附有注释,指出我所做的更改:
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
def func(l):
尺寸=长度(l)
对于范围((大小//2)-1,-1,-1)中的根:
root_val=l[root]#保存根值
child=2*root+1
虽然(child上面的解释很好,但这里有一个小小的修订版本:
# 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
\heapify到位
def heapify(A):
#在这里编写代码
对于xrange(len(A)//2-1,-1,-1)中的根:
rootVal=A[root]
child=2*root+1
当儿童A[child+1]:
儿童+=1
如果rootVal,root的子元素应该位于位置2*root和2*root+1吗?@MicahSmith:如果索引是以零为基础的,就不应该了,就像在Python中一样。root的子元素是2*root+1
和2*root+2
@Blckknght听起来不错。在我的DS课程中,我们学会了将root放在索引1中,而将索引0留空。(既允许上面的图案,又在heapify期间用作占位符。)