通过键区分优先级队列堆的时间复杂度



我有一个优先级队列最大堆,其中每个元素都是一个名为 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
}

堆显然是按优先级排序的。我要执行的操作是找到优先级最高的项目,递减其 Time 值,并在时间分数更改为 0 时将其从堆中删除。但是,这里有一个问题:允许有多个具有相同优先级的任务。在本例中,我比较所有此类任务的 ID 分数,并对最低的任务进行操作。

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

java.util.PriorityQueue

(Task个实例(构造函数可以采用可以考虑Task#PriorityTask#IDComparator,这意味着(优先级(关系可以根据(据说(唯一的 ID 被打破。因此,任务t1(Priority=5, ID=100, Time=10)可以先于(即优先于(任务t2(Priority=5, ID=110, Time=10)

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

最新更新