当前位置: 首页 > 面试题库 >

Python:从堆中删除元素

步博艺
2023-03-14
问题内容

Python具有heapq实现堆数据结构的模块,并且它支持一些基本操作(推送,弹出)。

如何从O(log n)中的堆中删除第i个元素?甚至可以使用heapq还是必须使用另一个模块?

请注意,文档底部有一个示例:http :
//docs.python.org/library/heapq.html
,它建议了一种可能的方法-这不是我想要的。我希望删除元素,而不仅仅是标记为已删除。


问题答案:

您可以很容易地从堆中删除第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()
if i < len(h):
    heapq._siftup(h, i)
    heapq._siftdown(h, 0, i)

请注意,在每种情况下您都不能这样做h[i] = h.pop(),因为如果i引用最后一个元素,该操作将失败。如果特殊情况下删除最后一个元素,则可以结合覆盖和弹出。

请注意,根据堆的典型大小,您可能会发现,仅heapify在理论上效率较低的情况下进行调用可能比重用_siftup/快一些_siftdown:进行一些自省会发现这heapify可能是用C实现的,但是内部函数的C实现没有暴露。如果性能对您很重要,则可以考虑对典型数据进行一些时序测试,以了解哪种方法最好。除非您的堆真的很大,否则大O可能不是最重要的因素。

编辑: 有人试图编辑此答案,以删除_siftdown带有以下内容的通话:

不需要_siftdown。保证新h [i]是旧h [i]的最小子项​​,但仍大于旧h [i]的父(新h
[i]的父)。_siftdown将为空。由于我没有足够的代表来添加评论,因此我必须进行编辑。

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

同样在询问为什么不仅仅用于sort()还原堆的评论中:调用_siftup_siftdown都是O(log
n)操作,调用heapify就是O(n)。调用sort()是一个O(n log n)操作。调用排序很有可能足够快,但是对于大堆来说,这是不必要的开销。

编辑 以避免@Seth
Bruder指出的问题。当i引用end元素时,_siftup()调用将失败,但是在那种情况下,将元素从堆的末端弹出不会破坏堆的不变性。



 类似资料:
  • 关于如何在Java代码中管理密码,有各种各样的问题和答案——例如,这里和这里。 讨论往往集中在使用< code>char[]而不是< code>String的优点上。 但是,如果是第三方库将密码存储在字符串中,有什么方法可以避免密码存储在JVM的堆中呢? 例如,在以下三种情况下,我认为密码将在JVM的生命周期内保留在堆中: 编辑-示例更新为与我的问题更相关: 在上面的示例中,我的对象在中包含密码。

  • 问题内容: 我已经看过这篇文章: Python:通过删除每个第n个元素从现有列表构建新列表,但是由于某些原因,它对我不起作用: 我这样尝试: 此函数需要一个列表和。然后,它使用列表中的n步删除第n个元素,并打印结果。 这是我的函数调用: 错误的输出: 代替 然后我从上面的链接尝试了一个变体: 再次,函数调用: 给了我同样的错误的结果: 不是 如何正确地从列表中删除/删除/删除 第n个 项目? 问题

  • 问题内容: 我陷入了XML和Python的困境。任务很简单,但到目前为止我还无法解决,花了那么长时间。我是来这里咨询如何用几行解决它的。 感谢您对遍历树的任何帮助。我总是以太多或太少的元素结束。元素可以无限制地嵌套。给出的例子只是一个例子。我会接受任何解决方案,而不是对dom,minidom,sax等等不挑剔。 我有一个与此类似的XML文件: 我需要的是-解析XML并编写一个新文件。新文件应包含给

  • 本文向大家介绍在Python中从元组中删除字符串,包括了在Python中从元组中删除字符串的使用技巧和注意事项,需要的朋友参考一下 当需要从元组中删除字符串时,可以使用列表理解和'type'方法。 列表可用于存储异构值(即,任何数据类型的数据,例如整数,浮点数,字符串等)。 元组列表基本上包含包含在列表中的元组。 列表理解是迭代列表并对其执行操作的一种快捷方式。 'type'方法返回作为参数传递给

  • 问题内容: 当我尝试使用迭代器从CopyOnWriteArrayList删除元素时,出现异常。我注意到它已记录在案 不支持对迭代器本身进行元素更改操作(删除,设置和添加)。这些方法抛出UnsupportedOperationException。 (来自http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWr

  • 问题内容: 当您将鼠标悬停在元素上时,我的CSS会更改格式。 HTML: CSS: 在某些情况下,我不想在悬停时应用CSS。一种方法是使用jQuery从div中删除CSS类,但这会破坏其他事情,因为我也使用该类来格式化其子元素。 因此,我提出了一个问题:是否有办法从元素中删除“悬停” css样式? 问题答案: 我将使用两个类。保留测试类,并添加一个名为testhover的第二类,该类仅添加到您要悬