【问题标题】:How do I get a Priority Queue to re-sort itself如何让优先队列重新排序
【发布时间】:2014-11-18 22:56:45
【问题描述】:

我有一个优先队列,用于跟踪员工列表,并且它用于在开始时对它们进行排序的比较器按当前的“邀请值”对它们进行排序。所以我想选择最大邀请值员工,邀请他,然后重新选择下一个最大邀请值员工。棘手的部分是,在我邀请某个员工后,它会影响列表中其他一些员工的邀请值。我已经尝试了以下

PriorityQueue<Employee> leafs = new PriorityQueue<>();
//populating the queue happens here

while(!leafs.isEmpty()){

Employee maxLeaf = leafs.peek();
        int maxValue = maxLeaf.getInviteValue();

        maxLeaf.invite();
        totalValue += maxValue;
        k--;

        for(Employee e : leafs){
            if(e.invValueChanged){
                leafs.remove(e);
                leafs.add(e);
            }
        }
}

每位员工都会通过查看其 invValueChanged 字段来了解是否需要根据上次邀请重新计算其价值。这段代码给我一个优先队列错误

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.PriorityQueue$Itr.next(PriorityQueue.java:535)

【问题讨论】:

  • 把它们全部拿出来。把它们全部放回去。PriorityQueue 没有排序。
  • @SotiriosDelimanolis 这将花费太长时间。我正在使用优先级队列来提高效率。有什么结构可以更好地解决这个问题吗?
  • 那将花费太长时间这正是您当前正在做的事情,但是您做错了。您不能在结构上更改您正在迭代的数据结构。

标签: java priority-queue


【解决方案1】:

这里的问题是,您需要更改数据结构中的其他元素。

你不能只对它们进行迭代,并对它们进行操作,这会改变元素的顺序。

最好的方法是创建当前结构的向量,对向量进行操作,然后重新插入。

如果速度是困扰您的问题,那么此操作与您编写的代码具有相同的时间复杂度。

在优先级队列中插入一个元素需要 O(log(n)) 时间,你这样做 n 次,所以你得到 O(n log(n)) 时间。

从一个先验队列中创建一个向量需要 O(n) 时间。从向量中插入优先级队列中的所有元素,需要 O(n log(n)) 时间。

所以速度应该是渐近相同的。 实际速度应该也很接近。

【讨论】:

    猜你喜欢
    • 2012-11-01
    • 2014-08-05
    • 2011-10-20
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    相关资源
    最近更新 更多