具有更改键值的优先级队列
Priority queue with changing values of key
我必须模拟一个优先队列。队列中的键会定期更改。队列必须能够:添加和删除元素。最好的方法是什么(拥有最好的复杂性)?什么是最好的数据结构?
我推荐以下两种方法:
- (高级)使用Java的PriorityQueue实现中使用的堆数据结构。当元素的优先级发生变化时,您需要在堆上执行"向上筛选"answers"向下筛选"操作,以确保堆的顶部仍然代表优先级队列中最高的元素。向上筛分和向下筛分是堆排序的一部分。
- (简单)使用无序列表作为优先队列。这意味着可以在0(1)访问时间内插入元素,并且调整元素的优先级不涉及对数据结构的任何操作。然而,权衡是访问最高优先级元素是O(n)。
如果您正在寻找一种数据结构,它可以支持任意键的不断更改,以及任意键的删除/添加[任意==不是这个答案中的头],那么常规堆将无法做到这一点,因为它不能保证快速搜索任意元素,只能搜索到头。
你可以选择一个完全有序的结构,比如平衡的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);
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 使用2个键的cpp-stl::优先级队列排序不正确
- 为什么我需要C++中不同的排序格式来对这个USACO代码上的数组和优先级队列进行排序
- 打印优先级队列
- 带自定义比较器的最小优先级队列
- 优先级队列自定义比较器
- 排序数组优先级队列
- 更改运行时优先级队列的排序功能
- 优先级队列构造函数的工作
- 实现优先级队列
- 优先级队列功能比较
- 在C++中打印对的优先级队列的所有值时出现问题
- 使用堆的优先级队列,具有相同键的值不遵循 FIFO(先进先出)
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 是否可以使用简单队列创建优先级队列
- 如何在 c++ 中创建对的优先级队列.这会弹出具有最小值的元素.默认的弹出最大值
- Cython中带有自定义比较器的优先级队列
- 优先级队列比较器[C++].
- asio::io_service 具有多个线程的优先级队列处理