一些背景知识:我正在构建一个C++
线程管理器,它允许用户创建一个AsyncJob
对象并分配执行的优先级。我有一个JobManager
单例类,它管理这些AsyncJobs
的优先级队列,并在可用时将它们分配给一个线程。
问题:用户需要能够修改优先级AFTER
的创建。例如,基于某些运行时事件,可能需要比其他文件更紧急地加载文件。我面临的问题是优先级队列只在调用push()
或pop()
时重新排序内部堆上的元素。据我所知,没有暴露的界面允许人们根据不断变化的优先级请求重新排序。
我想做的是这样的事情:
hashmap
类中创建一个JobManager
,其中包含指向优先级队列中对象的指针JobManager
向优先级队列发出优先级已更改的信号最好的解决方法是什么?我应该期望创建自己的自定义优先级队列类吗?或者可以从std::priority_queue
?
谢谢!
答案 0 :(得分:3)
一个选项可能是允许您的AsyncJob取消'取消'在取消旧的优先级后,每次修改优先级时,只需将AsyncJob的新(副本)添加到PQ。
与许多事情一样,我建议采用“最好的方式”。是非常主观的,因为它取决于你是多么受限制,以及你如何量化最好的'。就个人而言,我希望避免从标准库类型派生并尽可能重新发明容器结构。
答案 1 :(得分:2)
binary search tree似乎是一个不错的选择。
二进制搜索树应按优先级排序,其次,如果优先级不是唯一的,则对象中的唯一标识符/标识符集。
如果您想要更改以前的优先级,那么您需要一种方法来查找 - 可能是hash table优先级的对象。
这允许您删除并重新插入O(log n)
中的特定项目,而不会失去其他操作的O(log n)
性能(并O(1)
获得第一个)。
对于C ++:
如果优先级是唯一的,则对象的map
优先级可以有效,否则set
<
pair
>
其中第一个元素是优先事项,第二个是对象(是的,我知道,那些不一定是BST&#39;)。
对于哈希表,您可以使用unordered_map
对象作为优先级,或者只使用map
预C ++ 11。
答案 2 :(得分:1)
删除更改其优先级然后添加它的项目(或副本,如果新优先级在逻辑上意味着新项目)可能是最简单的方法。毕竟,您不想从头开始重新排序整个队列,只需更改单个项目 - 删除它并插入它就可以了。
编辑:但是,正如Paul Renton所提到的那样,std::priority_queue
不允许在没有poppinh的情况下获取单个项目,因此我使用std::vector
滚动我自己的优先级队列来自std::priority_queue
的灵感,默认使用std::vector
。我仅公开我需要的内容,而不是std::priority_queue
的整个API集。我不是使用整个列表,而是允许删除和插入按优先级正确排序的项目。