我不知道如何在不使用_siftup
or 的情况下有效地解决以下问题_siftdown
:
当一个元素无序时,如何恢复堆不变式?
换句话说,更新old_value
中heap
至new_value
,并保持heap
工作。您可以假设old_value
堆中只有一个。功能定义如下:
def update_value_in_heap(heap, old_value, new_value):
这是我的真实场景,有兴趣的可以看看。
你可以想象它是一个小型的自动完成系统。我需要统计单词出现的频率,并保持前k个max-count单词,随时准备输出。所以我heap
在这里使用。当一个字数++时,如果它在堆中,我需要更新它。
所有的词和计数都存储在 trie-tree 的叶子中,heaps
存储在 trie-tree 的中间节点中。如果你关心
堆外这个词,别担心,我可以从trie-tree的叶子节点中得到它。
当用户输入一个单词时,它将首先从堆中读取然后更新
它。为了获得更好的性能,我们可以考虑通过批量更新来降低更新频率。
那么当一个特定的字数增加时,如何更新堆呢?
这是 _siftup 或 _siftdown 版本的简单示例(不是我的场景):
>>> from heapq import _siftup, _siftdown, heapify, heappop
>>> data = [10, 5, 18, 2, 37, 3, 8, 7, 19, 1]
>>> heapify(data)
>>> old, new = 8, 22 # increase the 8 to 22
>>> i = data.index(old)
>>> data[i] = new
>>> _siftup(data, i)
>>> [heappop(data) for i in range(len(data))]
[1, 2, 3, 5, 7, 10, 18, 19, 22, 37]
>>> data = [10, 5, 18, 2, 37, 3, 8, 7, 19, 1]
>>> heapify(data)
>>> old, new = 8, 4 # decrease the 8 to 4
>>> i = data.index(old)
>>> data[i] = new
>>> _siftdown(data, 0, i)
>>> [heappop(data) for i in range(len(data))]
[1, 2, 3, 4, 5, 7, 10, 18, 19, 37]
索引的成本为 O(n),更新的成本为 O(logn)。heapify是另一种解决方案,但效率低于_siftup或_siftdown。
但是_siftupand_siftdown是heapq中的protected成员,所以不建议从外部访问。
那么有没有更好更有效的方法来解决这个问题呢?这种情况的最佳实践?
感谢您的阅读,我真的很感谢它帮助我。:)
慕勒3428872
RISEBY
相关分类