我正在尝试将优先级队列实现为已排序数组支持的最小二进制堆。我试图让update_key函数在对数时间运行,但为了做到这一点,我必须知道数组中项目的位置。无论如何不使用地图这样做?如果是这样,怎么样?谢谢
答案 0 :(得分:2)
如果您真的希望能够更改任意元素的键,则堆不是数据结构的最佳选择。它给你的是:
的组合 1.的另一个好处是缺少指针意味着您对malloc/free
(new/delete
)的呼叫要少得多。
地图(在标准库中表示为平衡二叉树)为您提供其中的两个,添加
find()
。 因此,虽然您可以将另一个数据结构附加到堆中,将指针存储在堆中,然后通过指针使比较运算符取消引用,但您很快就会发现自己只需使用{的时间和空间的复杂性首先是{1}}。
答案 1 :(得分:0)
您的查找键功能应在log(n)时间内运行。您的更新(更改密钥)应该是恒定的时间。你的删除功能应该在log(n)时间内运行。你的插入函数应该是log(n)时间。
如果这些假设属实,请尝试以下方法: 1)在堆中找到你的项目(IE:二进制搜索,因为它是一个排序的数组)。 2)更新你的密钥(你只是改变一个值,恒定的时间) 3)从堆日志(n)中删除该项目以重新加密 4)将您的项目插入堆日志(n)。
所以,你有log(n)+ 1 + log(n)+ log(n),它减少到log(n)。
注意:这是分摊的,因为如果你必须重新分配你的数组等......这会增加开销。但无论如何你不应该经常这样做。
答案 2 :(得分:0)
这是数组支持堆的权衡:你获得了极好的内存使用(良好的局部性和最小的开销),但是你会忘记元素。要解决这个问题,你必须补充一些开销。
一种解决方案就是这样。堆包含C*
类型的对象。 C是一个int
成员heap_index
的类,它是堆数组中对象的索引。每当您在堆数组中移动元素时,您都必须更新其heap_index
以将其设置为新索引。
Update_key(以及删除任意元素)是log(n)时间,因为它需要花费不变的时间来查找元素(通过heap_index
),并记录log(n)时间以将其冒泡到正确的位置。