繁体   English   中英

更改键值的优先级队列

[英]Priority queue with changing values of key

我必须模拟一个优先级队列。 队列中的密钥会定期更改。 队列必须能够:添加元素和删除元素。 最好的方法是什么(最复杂)? 最好的数据结构是什么?

我建议使用以下两种方法之一:

  1. (高级)使用Java的PriorityQueue实现所使用的堆数据结构。 当元素的优先级更改时,您将需要对堆执行“向上筛选”和“向下筛选”操作,以确保堆顶部仍然代表优先级队列中的最高元素。 向上筛选和向下筛选是构成heapsort的一部分的操作
  2. (简单)使用无序列表作为优先级队列。 这意味着可以在访问时间为O(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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM