【问题标题】:Time Complexity of Differentiating Priority Queue Heap Via Key通过 Key 区分优先级队列堆的时间复杂度
【发布时间】:2017-12-05 14:56:11
【问题描述】:

我有一个优先级队列最大堆,其中每个元素都是一个名为 Task 的类,如下所示(用 Java 实现,但问题与语言无关):

class Task{

    int ID
    int Priority
    int Time

    public Task(int i, int p, int t){
        this.ID = i;
        this.Priority = p;
        this.Time = t;
    }

    //Getters, etc
}

堆显然是按优先级排序的。我要执行的操作是找到最高优先级的项目,递减它的时间值,如果时间分数变为 0,则将其从堆中删除。但是,这里有一个问题:允许有多个任务与相同的优先级。在这种情况下,我会比较所有此类任务的 ID 分数,然后对最低的一个进行操作。

这种操作的最坏情况下的运行时间是多少?如果每个元素具有相同的优先级,我最终会搜索整个树,这意味着这不可能在少于 O(n) 的时间内完成,对吗?这似乎无法解决,因为 ID 未排序。但是,有人告诉我,这可以在 O(log n) 中完成,我完全不明白。谁能澄清我在哪里接近这个错误?

【问题讨论】:

  • 您选择的标签没有很多关注者,我建议您使用语言标签,即使问题与语言无关

标签: java heap binary-tree scheduling priority-queue


【解决方案1】:

java.util.PriorityQueueTask 实例)constructor 可以采用 Comparator,它可以考虑到 Task#PriorityTask#ID,这意味着可以根据 ID 打破(优先级)关系(据说)是独一无二的。因此,任务t1(Priority=5, ID=100, Time=10) 可以先于(即优先于)任务t2(Priority=5, ID=110, Time=10)

删除具有最高优先级的此类项目(位于根目录)以及可能具有相同优先级的其他项目,剩余时间为零最低 ID 仍然是 O(log(n)) 操作堆或优先队列,同时保持堆属性。请注意,优先级队列不适合搜索(哈希表或二叉搜索树做得很好);但用于在保持堆属性的同时插入或删除。您应该只使用 peekremove API 方法来实现您需要的操作,同时确保优先级队列设计的时间复杂度 (O(log n))。

【讨论】:

  • 我应该澄清一下,我没有使用 PriorityQueue,我将堆存储在一个数组中。但是你的回答给了我一个想法,如果优先级相同,我可以在我的插入中添加一个额外的条件,将较低的 ID 推到堆上。然后我上面描述的操作每次都必须对根进行。不是直接的答案,但你让我想到了正确的方向,所以谢谢!
  • 在我没有使用 PriorityQueue 实用程序的意义上,我是从头开始创建实现的。我知道 PriorityQueue 也使用了一个数组,这本来可以更好的措辞。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多