python删除元素_Python:从堆中删除元素

您可以很容易地从堆中删除第i个元素:

h[i] = h[-1]

h.pop()

heapq.heapify(h)

只需用最后一个元素替换要删除的元素,并删除最后一个元素,然后重新堆叠堆。这是O(n),如果你希望你可以在O(log(n))中做同样的事情,但是你需要调用几个内部的heapify函数,或者更好的是,larsmans指出只需复制_siftup / _siftdown从heapq.py到你自己的代码:

h[i] = h[-1]

h.pop()

heapq._siftup(h, i)

heapq._siftdown(h, 0, i)

请注意,在每种情况下,您不能只是h [i] = h.pop(),因为如果我引用最后一个元素将失败。如果特殊情况下删除最后一个元素,那么可以组合覆盖和弹出。

请注意,根据堆的典型大小,您可能会发现只是调用heapify,而理论上效率较低的可能比重新使用_siftup / _siftdown更快:一点反思会显示heapify可能在C中实现,但C实现的内部功能不暴露。如果性能重要,那么您可以考虑对典型数据进行一些时序测试,以查看哪个是最佳的。除非你真的很大,否则大O可能不是最重要的因素。

编辑:有人尝试编辑此答案,以删除对_siftdown的调用,并附有以下注释:

_siftdown is not needed. New h[i] is guaranteed to be the smallest of the old h[i]’s children, which is still larger than old h[i]’s parent

(new h[i]’s parent). _siftdown will be a no-op. I have to edit since I

don’t have enough rep to add a comment yet.

在这个评论中他们错过的是,h [-1]可能不是h [i]的孩子。在h [i]插入的新值可能来自堆的完全不同的分支,因此可能需要在任一方向筛选。

另外给注释问为什么不只是使用sort()来恢复堆:调用_siftup和_siftdown都是O(log n)操作,调用heapify是O(n)。调用sort()是一个O(n log n)操作。调用排序很有可能是足够快的,但是对于大的堆,这是一个不必要的开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>