我做了一些计算,似乎三元堆总是优于二元堆,而四元堆有时会优于三元堆。
令c、s分别表示比较和交换所需的时间。假设我们有一个长度为 n 的 k 元堆。堆支持两种基本操作:
然而,这就是我真正困惑的地方:比较 k = 2 和 3,您实际上会发现对于提取最大值和插入, 3总是比 2 更好。(我也不会写出方程,但这部分是因为 3^2 > 2^3)。
那么我们为什么不使用三元堆呢?为什么我们总是使用二叉堆?
事实上,我们确实使用三元或四元堆。一般来说,它被称为d 进制堆。你是对的:理论上,3 堆应该比 2 堆更快,4 堆应该和 2 堆一样快。我在博客http://blog.mischel.com/2013/10/05/the-d-ary-heap/中写了一些相关内容。
\n\n\n\n\n应该清楚的是,将项目添加到 4 堆会比将项目添加到相同大小的 2 堆更快。例如,如果您想要向上面所示的 4 堆添加一个项目,BubbleUp 最多会执行 3 次迭代。具有 20 个节点的二叉堆需要 5 个级别,这意味着您可能需要进行最多 5 次迭代。
\n\n不过,没有什么\xe2\x80\x99s是免费的。移除变得更加昂贵。尽管级别较少,但随着 d 的增加,SiftDown 方法中循环的每次迭代都会花费更长的时间。对于二叉堆,您只需在每次迭代时进行两个节点比较(查找最小子节点需要进行一次比较,而将您插入的节点与最小子节点进行比较则需要进行另一个比较) )。4 堆需要筛选的级别较少,但每个级别都需要更多处理,因为它必须进行四次比较才能找到最小的子级。
\n
不幸的是,渐近分析并不是故事的全部。二进制堆允许您实现一些在 3 堆及更高堆中不可能实现的快捷方式。随着堆的顺序增加,当你筛选堆时找到最小的孩子会变得越来越昂贵,并且这会抵消大部分理论上的性能增益。
\n\n在我的实验中,我发现 3 堆几乎总是比二进制堆更快,尤其是当比较非常昂贵时。在某些情况下,4 堆和 5 堆的性能优于 3 堆,但还不足以值得使用它们。
\n\n对于我自己的工作,我几乎总是使用优化的三元堆,因为它通常比我的优化的二进制堆更快。但我已经设置了代码,因此我所要做的就是更改一行以从三元堆转换为二进制堆。
\n