最大堆插入函数python
Posted
技术标签:
【中文标题】最大堆插入函数python【英文标题】:Max Heap insert function python 【发布时间】:2022-01-04 10:47:13 【问题描述】:我为最大堆编写了这个插入函数:
def insertinmaxheap(arryhp, num):
arryhp.append(num)
arryhp.insert(0, 0)
l = len(arryhp) - 1
b = True
while b:
print(arryhp)
print(l)
print(int(l/2))
if num <= arryhp[int(l / 2)] or int(l/2) < 2:
b = False
arryhp[l] = arryhp[int(l/2)]
arryhp[int(l/2)] = num
l = int(l/2)
return arryhp[1:len(arryhp)]
我已经针对一些值进行了测试,并且大部分时间都可以正常工作,但是对于本示例,它失败了:
insertinmaxheap([50, 30, 20, 15, 10, 8, 16], 19)
输出为 [50, 19, 20, 30, 10, 8, 16, 15],如您所见,不应该存在 19。
这段代码有什么问题?
【问题讨论】:
至少,缩进看起来没有。 你是什么意思?在哪里? 第 2 行及以下。我不知道python,但我很确定那些应该缩进一级。 使用l//2
或l>>1
,而不是int(l/2)
。
【参考方案1】:
有两个问题:
在将b
设置为False
之后,在退出循环之前仍会执行交换。执行应使用break
跳出循环。这也使得布尔值b
变得不必要。
条件int(l/2) < 2
应该是int(l/2) < 1
,因为实际上应该与索引 1 处的父级进行比较。
其他说明:
使用整数除法运算符而不是浮点除法。
当你切到最后时,使用1:len(arryhp)
,你可以省略冒号后面的部分:1:
。
返回的列表不是作为参数给出的变异列表,这不好。输入列表不应该被变异,或者返回的列表是变异的输入列表。后者可以通过使用.pop(0)
从列表中弹出第一个值来完成。
以下是这些更改的代码:
def insertinmaxheap(arryhp, num):
arryhp.append(num)
arryhp.insert(0, 0)
l = len(arryhp) - 1
while True:
if num <= arryhp[l // 2] or l // 2 < 1:
break
arryhp[l] = arryhp[l//2]
arryhp[l // 2] = num
l = l // 2
arryhp.pop(0)
return arryhp
现在,这不是有效的。该虚拟值的插入和弹出正在消除该算法的时间复杂度。您最好不要插入该虚拟值并使用适当的表达式来确定父/子关系。
此外,您不必在循环的每次 迭代中将num
分配给堆中的新槽。在循环结束并确定num
的最终目的地之后,这样做一次就足够了:
def insertinmaxheap(arryhp, num):
arryhp.append(num)
l = len(arryhp) - 1
while l > 0:
parent = (l - 1) // 2
if num <= arryhp[parent]:
break
arryhp[l] = arryhp[parent]
l = parent
arryhp[l] = num
return arryhp
【讨论】:
非常感谢......但我还有一个额外的问题:使用这个 insertinmaxheap() 函数或只是将元素附加到列表然后简单地使用 heapify() 方法会更优化。 如果heapify
采用自下而上的方式实现,则第二种方式效率更高。见How can building a heap be O(n) time complexity?以上是关于最大堆插入函数python的主要内容,如果未能解决你的问题,请参考以下文章