繁体   English   中英

优先级队列 - 二进制堆

[英]Priority Queue - Binary Heap

我正在尝试将优先级队列实现为排序数组支持的最小二进制堆。 我试图让update_key函数在对数时间运行,但为了做到这一点,我必须知道数组中项目的位置。 无论如何不使用地图这样做? 如果是这样,怎么样? 谢谢

如果您真的希望能够更改任意元素的键,则堆不是数据结构的最佳选择。 它给你的是以下组合:

  1. 紧凑表示(没有指针,只是一个数组和一个隐式索引方案)
  2. 对数插入,重新平衡
  3. 对数去除最小(最大)元素。
  4. O(1)访问最小(最大)元素的值。 -

1.的另一个好处是缺少指针意味着你对malloc/freenew/delete )的调用少得多。 地图(在标准库中表示为平衡二叉树)为您提供其中的两个,添加

  1. 任何键上的对数find()

因此,虽然您可以将另一个数据结构附加到堆中,将指针存储在堆中,然后通过指针使比较运算符取消引用,但您很快就会发现自己在第一次使用map时的时间和空间的复杂性地点。

您的查找键功能应在log(n)时间内运行。 您的更新(更改密钥)应该是恒定的时间。 你的删除功能应该在log(n)时间内运行。 你的插入函数应该是log(n)时间。

如果这些假设为真,请尝试以下方法:1)在堆中找到您的项目(IE:二进制搜索,因为它是一个排序数组)。 2)更新你的密钥(你只是改变一个值,恒定的时间)3)从堆日志中删除项目(n)以重新密化。
4)将您的项目插入堆日志(n)。

所以,你有log(n)+ 1 + log(n)+ log(n),它减少到log(n)。

注意:这是分摊的,因为如果你必须重新分配你的数组等...这会增加开销。 但无论如何你不应该经常这样做。

这是数组支持堆的权衡:你获得了极好的内存使用(良好的局部性和最小的开销),但你忘记了元素。 要解决它,你必须添加一些开销。

一个解决方案就是这样。 堆包含C*类型的对象。 C是一个带有int成员heap_index的类,它是堆数组中对象的索引。 每当您在堆数组中移动元素时,您都必须更新其heap_index以将其设置为新索引。

然后Update_key(以及删除任意元素)是log(n)时间,因为它需要恒定的时间来查找元素(通过heap_index ),并且log(n)时间将其冒泡到正确的位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM