0

让A成为一个堆,它不是以常规方式存储值,而只是定期存储根,并且每个子存储为它与其父项之间的差异。 HEAP-INCREASE-KEY(A,i,key)操作的复杂性是什么(操作更新节点上的节点的key到key)?HEAP-INCREASE-KEY复杂度

+0

“key”是节点'i'的值与父值的差值,还是节点'i'的实际值?操作只能增加数值还是可以减少差值?这个问题在这里是边界线(无论是主题还是容忍)。我建议在此删除它并将其张贴在[cs.se]上,然后放在主题上,更有可能被主题专家看到。 – Gilles 2014-11-08 17:30:26

+0

这个问题似乎是题外话题,因为它是关于计算机科学,而不是编程。 – Gilles 2014-11-08 17:31:12

回答

1

它可以在O(log N)时间像在一个正常的堆中完成。要找到存储在节点i中的新值,可以遍历从堆根目录到此节点的路径,以便根据它与其父节点之间的差异表示新的key值。之后,筛选程序可以以与在普通堆中完成的方式几乎相同的方式执行。在进行筛选程序交换时,这些值只会改变这两个交换节点及其子元素。因此,一次交换需要更新O(1)。这就是为什么总时间复杂度为O(log N)

这是实现它的一种简单方法:
1.如果节点位于堆根和更新节点之间的路径上,我们称它为“已触及”节点。如果节点与最接近的“已触摸”节点之间的距离至多为2,我们称节点为“重建”。
2.对于每个“重建”节点,可以通过遍历堆来计算其真值。请注意,对于任何查询,都有O(log N)“重建”节点。
3.重建所有“重建”节点的真值后,可以运行一个通常的筛选程序。
4.在此过程完成后,可以通过遍历所有“重建”节点的堆来计算节点与其父节点之间的差异。所有其他节点都不会被触摸。

+0

你能解释一下在这种情况下筛分过程是如何进行的吗? – Guy 2014-11-08 17:54:39

+0

@Guy节点值与其父值之间的差异是已知的。所以很明显它们是否应该交换。 – kraskevich 2014-11-08 17:57:26

+0

当你说“他只为这两个交换节点及其子节点改变值”时,有多少节点发生了改变?我不明白这一部分。 – Guy 2014-11-08 17:59:53