我一直试图解决这个问题几天了。我在学校遇到以下问题:
让A成为最小堆。操作 HEAP-MODIFY(A,i,k)改变键 然后,在节点i中新的值为k 重新排列最小堆中的元素。 给出一个实现 在O(lgn)时间运行的HEAPMODIFY 对于n元素的最小堆。
由于我们必须设计一个在O(lg(n))时间内运行的算法,我知道我不能只迭代每个元素。我有以下解决方案,但我不确定它是否正确。
HEAP-MODIFY(A,i,k):
A[i] = K
if A[i] < A[i/2]
while A[i] < A[i/2] and i > 1
exchange A[i], A[i/2]
i=i/2
else if A[i] > A[2*i]
while A[i] > A[2*1] and i <k
exchange A[i], A[2*i]
i = 2*1
有关如何解决这个问题的任何建议吗?
答案 0 :(得分:3)
您正在考虑正确的方向,但您执行的操作不会保证最小堆的结果。查看以下堆:
..
11
/ \
19 63 (<-was 13)
.. / \
55 15
.. ..
想象一下,您刚刚将密钥13更新为63并希望恢复最小堆属性。你的代码将交换55和63,因为55&lt; 63,但是55将是63和15(!)的父代,因此会损害最小堆属性。
您需要的功能(恢复最小堆属性)称为“heapify”。这不是微不足道的,但也不是很复杂。在这篇关于heapsort的维基百科文章中查找其解释。只要您理解而不仅仅是复制,只需阅读/学习解决方案就没有错。
如果您之后仍有疑问,请询问。
答案 1 :(得分:3)
您可以找到并删除Node(i),将Node的值更改为k并将其重新放回堆中。这不是最有效的方法,但它仍然是log(n)。优点是它很简单,可能会重复使用已经实现的操作。
答案 2 :(得分:1)
HEAP-MODIFY(A,i,K)
A[i] = K
MIN-HEAPIFY(A,1)
我也在研究这个问题,并得到了这个。 我和你一样困惑,但我觉得你的代码过于复杂。