当前位置: 首页 > 知识库问答 >
问题:

具有重写比较器的优先级队列

尚俊楠
2023-03-14

我在Java使用PriorityQueue。

我有一个结构如下的对象:

public class CostObject {

  String value;
  double cost;

  public CostObject(String val, double cst) {
    value = val;
    cost = cst;
  }
}

优先考虑的是从最便宜到最贵的成本:

PriorityQueue<CostObject> queue = new PriorityQueue<>(1, new Comparator<CostObject> () {

    @Override
    public int compare(CostObject co1, CostObject co2) {
            return (co1.cost > co2.cost) ? 1 : -1;
    }

});

我使用add将对象包含在队列中。

CostObject co = new CostObject("test", cost);
queue.add(co);

它适用于队列中的每个元素,但我添加的最后一个元素总是位于底部。

我做错了什么?

共有2个答案

范华清
2023-03-14

比较器永远不能返回0。这至少违反了comparator.compare通用合同中的一个规则,即:

sgn(compare(x, y)) == -sgn(compare(y, x))

如果xy具有相同的代价,则compare(x,y)compare(y,x)都将是-1。

您应该使用double.comparecomparator.comparingdouble来正确实现比较器:

new PriorityQueue<>(1, new Comparator<>() {
    public int compare(CostObject co1, CostObject co2) {
        return Double.compare(co1.cost, co2.cost);
    }
});

或:

new PriorityQueue<>(1, Comparator.comparingDouble(CostObject::getCost));

正如Slimu在注释中提到的,您可能使用其迭代器(例如使用for循环)从队列中获取元素。这并不能保证给你的元素以正确的顺序,这可能是为什么“但最后一个我补充,它总是在底部的位置”。如果希望元素的顺序正确,则应该从队列中轮询

谭毅然
2023-03-14

优先级队列将只保证头部是最便宜的(或最小/最大的取决于比较器),但不保证在整体顺序上。如果您执行queue.poll()来检索和删除头,您将按顺序获得元素,因为每次轮询当前头时,优先级队列将确保新头是最便宜的元素

 类似资料:
  • 假设我实现了一个HashMap,其中字符被分配了一个值的ArrayList。 我已经在HashMap中创建了这些字符的PriorityQueue,但我希望能够根据此优先级删除这些字符: {a,b,c} {a,b}删除c,因为它的ArrayList中包含一个值,该值决定必须首先删除它。 对此最好的方法是什么?

  • 有人能解释一下这里使用的比较运算符的语法吗?它是做什么的

  • priority_queue,comparator(query,d)>min_heap; main.cpp:20:7:注意:“comparator”不是文字,因为: class comparator{ main.cpp:20:7:注意:“comparator”不是聚合,没有普通的默认构造函数,也没有不是复制或移动构造函数的constexpr构造函数 Main.cpp:92:65:注意:应为类型,但

  • 我使用的是PriorityQueue和我自己的比较器,但最终结果并不总是好的。我应该按平均成绩、姓名、身份证进行排序。最后,它应该返回队列中剩余的名称。其余的名字都很好,但顺序不同。输入(名称、平均等级、识别号): 预期产出: 我的结果: 你能帮我找出问题所在吗?提前谢谢你!

  • 我刚开始学习C语言,有一半的时间我不知道自己在做什么,花了好几个小时在谷歌上搜索,盲目地在我的项目中输入代码,这可能是一个基本的问题,但我似乎不能正确地理解它。 这是我作业的要求,我需要这些: 在“边”类中: 在Graph类中: 我在声明优先级队列时遇到问题。细节: 如果我直接使用这些,edge类会给我一个错误“必须有类的参数”,我知道我不能将两个指针重载到bool运算符中,所以我尝试了以下方法:

  • 我需要一个优先级队列,它首先获得具有最高优先级值的项目。我当前正在使用队列库中的PriorityQueue类。但是,这个函数只先返回值最小的项。我尝试了一些很难看的解决方案,比如(sys.maxint-priority)作为优先级,但我只是想知道是否存在更优雅的解决方案。