首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >排序列表vs堆:删除列表中间的元素Python

排序列表vs堆:删除列表中间的元素Python
EN

Stack Overflow用户
提问于 2018-08-27 02:44:31
回答 2查看 395关注 0票数 0

我有一个不断更新的列表结构。在每次迭代中,将执行以下步骤:

  • 删除列表中的最小值
  • 删除列表中某处的n值
  • 将n值添加到列表

据我所知,堆在这里不是一个好的解决方案(即使是懒惰的删除),因为我需要删除列表中我不知道索引(位置)的某个地方的值。因此,需要搜索这些值。

我是否只使用排序列表来解决此问题?我需要在这里获得最好的性能,因为列表在循环中的某个点上最多有100.000个元素。

EN

回答 2

Stack Overflow用户

发布于 2018-08-27 03:22:05

如果这些值可以用作dict键,那么可以很容易地同时使用堆和collections.Counter来跟踪每个值在概念上仍在集合中的数量。计数为0表示该值在概念上已被完全删除,尽管它可能仍存在于堆中。

下面是一个草图(未测试!),其中ccollections.Counter的实例,h是用作heapq模块操作堆的列表:

要添加元素(expected case时间对数,以堆大小表示):

代码语言:javascript
复制
heapq.heappush(h, elt)
c[elt] += 1

要删除元素(expected case常量时间),请执行以下操作:

代码语言:javascript
复制
if not c[elt]:
    raise ValueError("element doesn't exist")
c[elt] -= 1
if not c[elt]:
    del c[elt]

要删除最小元素(从堆中弹出的每个概念上已经删除的项的预期大小写对数时间(在堆的缩小大小中)):

代码语言:javascript
复制
while True:
    if not h:
        raise ValueError("cannot find minimum in empty collection")
    elt = heapq.heappop(h)
    if c[elt]:
        c[elt] -= 1
        if not c[elt]:
            del c[elt]
        break
    # else the Counter believes it was deleted earlier
票数 1
EN

Stack Overflow用户

发布于 2018-08-27 03:21:23

通过在堆旁边维护一个字典,可以避免不知道要删除的项的索引的问题。字典中的值与堆项目相同(可能是一个具有优先级值和对实际项目的引用的列表)。字典中的关键字与真实条目相同,因此很容易查找。

当您想要删除一个不是最小项的项时,您可以在字典中查找它并将其标记为已删除(可能是通过将对该项的引用设置为None)。不需要修改表示堆的列表,它具有对相同项的引用,因此它将看到该项已被删除,这是最低限度的删除。

也就是说,如果您经常执行“从数据中的任何位置删除项”操作,那么使用常规字典或集合可能会更好。您可以使用min在线性时间内获得最小值,而删除(任何项目,包括最小值)需要恒定的时间(平均摊销)。对于某些使用模式,这可能比处理堆更快。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52029286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档