我一直在寻找最小堆实现的变体,该变体不是提供用于减少键的摊销O(1),而是提供用于增加键的O(1)。 (由于需要以成本为o(log(n))来减少键,因此需要权衡取舍,因为观察到here,所以不可能同时做到这两种情况。
我实际上有一组固定大小的元素,我想对这些键进行递增,或者用最小的元素替换最小的元素。因此,另一种满足此要求的方法也很棒!
有人知道使用恒定摊销时间增加键操作进行堆变化吗?
谢谢!
答案 0 :(得分:2)
我认为您优化得太早了。我建议您使用配对堆启动并运行应用程序,然后对其进行概要分析。关于数据以及堆结构将如何执行,您还有太多未知的事情。
二项堆,斐波那契堆,配对堆和许多其他变体很难分析,因为它们的行为在很大程度上取决于操作的混合,操作的顺序以及数据的性质。例如,在配对堆中,如果节点没有子节点,则 increase-key 为O(1)。节点是否有子节点取决于节点在堆中的位置以及 decrease-key 或 remove-first 的调用次数。
我怀疑您会发现具有O(1)删除和对数插入的堆结构。甚至对其他所有内容都具有O(1)的Brodal queue也可以删除O(log n)。但是请注意,尽管Brodal队列在渐近最优状态下,但是用Brodal自己的话来说,它是“相当复杂的”和“ [在实践中不实用”。
运行程序。剖析它。然后确定是否需要性能更高的优先级队列结构。
答案 1 :(得分:1)
实际上,您指向的链接表明,对于O(1)
,insert
和find-min
来说,您不能一起使用的三个操作是increase-key
。没有decrease-key
操作。因此,其他操作之一必须增加。我怀疑这是可能的。
但是,斐波那契堆确实提供了分摊的随机 O(1)
密钥增加。也就是说,对于一半的元素,您无需移动它。对于四分之一,您必须将其移动一次。对于1/8,您必须将其移动两次,依此类推。最坏的情况O(log(n))
仅在增加底部元素时才支付。因此,增加随机元素的平均成本为O(1)
。
您甚至可以使堆更好。当您增加元素的值时,可以将其标记为已增加,并使其实际上变得懒散。除非它到达底部,否则您根本不必移动它。因此,根据使用情况,大多数情况下,您不必为搬运物品而完全付费。