[英]Priority queue with changing values of key
我必须模拟一个优先级队列。 队列中的密钥会定期更改。 队列必须能够:添加元素和删除元素。 最好的方法是什么(最复杂)? 最好的数据结构是什么?
如果您正在寻找一种数据结构,该结构可以支持任意键的不断更改以及任意键的删除/添加[任意==不是此答案的开头],则常规堆将无法解决问题,因为它不会不能保证快速搜索任意元素,只能搜索头部。
您可以采用完全有序的结构,例如平衡的BST ,并在修改树时缓存最小/最大。 [最小值是最左边的元素,最大值是最右边的元素]。
这将使您:
删除,修改,添加: O(logn)
findMin / findMax: O(1)
总是很难说出“最佳”数据结构是什么。 通常,尽管很难更改项目的优先级,但是二进制堆会形成一个很好的优先级队列。 我过去所做的是创建一个结合字典和堆的数据结构。 字典由项目的标识符作为关键字,并跟踪堆中每个项目的位置。 当项目在堆中添加,删除或移动时,其位置将在字典中更新。 事实证明这是便宜的。
现在,当您想要更改项目的优先级或从优先级队列中删除任意项目时,可以在字典( O(1)
)中查找它,以获取其在堆中的位置。 从那里开始,它是一个O(log n)
操作来移动或删除它。
您还可以为您的优先级队列使用平衡的二叉树。 保留“最低节点”指针很容易,并且树上的操作为O(log n)
。 如果插入和删除操作分散得很好,则这应该表现得很好。 缺点是实现自平衡二叉树的代码有点麻烦。
另一种可能性是对优先级队列使用跳过列表 。 我的测试表明,跳过列表优先级队列与基于二进制堆的优先级队列相比具有优势,但是具有一个很大的优势:查找项目是O(log n)
而不是O(n)
。 而且,跳转列表的实现并不比二进制堆难得多。
我倾向于使用跳过列表,因为它比组合的堆/字典更易于管理,并且比平衡的二叉树性能更好。
如果您只是将数字存储为键,则ArrayList类应该可以正常工作。
queue = new ArrayList<int>;
queue.add(27);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.