我正在尝试使用列表数据结构实现堆。我还想跟踪列表中元素的位置,以便轻松删除。我的实现涉及循环遍历整个列表以在插入/删除组合之后更新位置。我担心这会将时间复杂度从O(log n)提高到O(n)。 有没有更好的方法来跟踪元素的位置?目前,更新方法是负责簿记的。
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
],
"mixins": [
"loopback/common/mixins",
"loopback/server/mixins",
"../common/mixins",
"./mixins"
]
},
... ,
"user": {
"dataSource": "mysql",
"public": true,
"options": {
"emailVerificationRequired": true
}
},
...
}
答案 0 :(得分:1)
如果您正在构建二进制堆,我知道的加速任意删除或更改优先级的最佳方法是创建哈希映射。键是优先级队列中的项,值是数组中的当前位置。将项目插入队列时,可以使用项目的当前位置向哈希映射添加条目。
然后,每次项目在队列中移动时,都会在哈希映射中更新其值。因此,每次在插入或删除期间进行交换时,都会更新该哈希映射中的交换项的值。
要删除任意项目,请执行以下操作:
这种方法运行得相当不错,但如果你的堆很大,它在内存方面可能相当昂贵。
其他堆数据结构,如Fibonacci堆,配对堆,Skew堆,甚至是作为二叉树实现的二进制堆,可以与单个堆节点一起工作,而不是在数组中使用隐式节点,因此可以直接访问而无需中间哈希表的。它们确实需要比作为数组实现的二进制堆更多的内存,但可能效率更高。
顺便说一下,如果你决定尝试其中一种替代结构,我建议你看一下配对堆。它的渐近性能几乎与Fibonacci堆一样好,并且很多更容易实现。我的实际表现还没有很好的数据。