[英]Priority queue with changing values of key
I must to simulate a priority queue. 我必须模拟一个优先级队列。 Keys in queue are periodically changed.
队列中的密钥会定期更改。 Queue must be able: add element and delete element.
队列必须能够:添加元素和删除元素。 What is the best way to do it (with the best complexity)?
最好的方法是什么(最复杂)? What is the best data structure?
最好的数据结构是什么?
I would recommend one of two approaches: 我建议使用以下两种方法之一:
If you are looking for a data-structure that can support constant changes in arbitrary keys, and removals/additions of arbitrary keys [arbitrary == not the head in this answer], a regular heap won't do the trick, since it doesn't guarantee quick search for arbitrary elements, only to the head. 如果您正在寻找一种数据结构,该结构可以支持任意键的不断更改以及任意键的删除/添加[任意==不是此答案的开头],则常规堆将无法解决问题,因为它不会不能保证快速搜索任意元素,只能搜索头部。
You could go for a fully ordered structure, such as a balanced BST , and cache the min/max whenever the tree is modified. 您可以采用完全有序的结构,例如平衡的BST ,并在修改树时缓存最小/最大。 [the min is the leftest element, the max is the rightest element].
[最小值是最左边的元素,最大值是最右边的元素]。
This will allow you: 这将使您:
delete,modify,add: O(logn)
删除,修改,添加:
O(logn)
findMin/findMax: O(1)
findMin / findMax:
O(1)
It's always difficult to say what the "best" data structure is. 总是很难说出“最佳”数据结构是什么。 In general, a binary heap makes a very good priority queue, although it is difficult to change an item's priority.
通常,尽管很难更改项目的优先级,但是二进制堆会形成一个很好的优先级队列。 What I did in the past is create a data structure that combines a dictionary and a heap.
我过去所做的是创建一个结合字典和堆的数据结构。 The dictionary is keyed by the item's identifier, and keeps track of each item's location in the heap.
字典由项目的标识符作为关键字,并跟踪堆中每个项目的位置。 When an item is added, removed, or moved in the heap, its location is updated in the dictionary.
当项目在堆中添加,删除或移动时,其位置将在字典中更新。 This turns out to be inexpensive.
事实证明这是便宜的。
Now when you want to change an item's priority or remove an arbitrary item from the priority queue, you can look it up in the dictionary ( O(1)
) to get its position in the heap. 现在,当您想要更改项目的优先级或从优先级队列中删除任意项目时,可以在字典(
O(1)
)中查找它,以获取其在堆中的位置。 From there, it's an O(log n)
operation to move or remove it. 从那里开始,它是一个
O(log n)
操作来移动或删除它。
You could also use a balanced binary tree for your priority queue. 您还可以为您的优先级队列使用平衡的二叉树。 It's easy enough to keep a "lowest node" pointer, and operations on the tree are
O(log n)
. 保留“最低节点”指针很容易,并且树上的操作为
O(log n)
。 If insertions and removals are fairly well scattered out, this should perform reasonably well. 如果插入和删除操作分散得很好,则这应该表现得很好。 The drawback is that the code to implement a self-balancing binary tree is a bit involved.
缺点是实现自平衡二叉树的代码有点麻烦。
Another possibility is to use a skip list for your priority queue. 另一种可能性是对优先级队列使用跳过列表 。 My tests show that a skip list priority queue compares favorably with a binary heap based priority queue, but has one big advantage: looking up an item is
O(log n)
rather than O(n)
. 我的测试表明,跳过列表优先级队列与基于二进制堆的优先级队列相比具有优势,但是具有一个很大的优势:查找项目是
O(log n)
而不是O(n)
。 And a skip list isn't much more difficult to implement than a binary heap. 而且,跳转列表的实现并不比二进制堆难得多。
I would tend toward using the skip list because it's easier to manage than the combined heap/dictionary, and it will perform better than the balanced binary tree. 我倾向于使用跳过列表,因为它比组合的堆/字典更易于管理,并且比平衡的二叉树性能更好。
If you're just storing numbers as keys, the ArrayList class should work fine. 如果您只是将数字存储为键,则ArrayList类应该可以正常工作。
queue = new ArrayList<int>;
queue.add(27);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.