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

最小优先级队列和最大优先级队列排序不正确[重复]

洪光霁
2023-03-14

我正在编写一个最小优先级队列和一个最大优先级队列,如下所示:

PriorityQueue<Double> max_pq = new PriorityQueue<>(new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                if(o1<o2) return +1;
                if(o1.equals(o2)) return 0;
                return -1;
            }
        });

        PriorityQueue<Double> min_pq = new PriorityQueue<>(new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                if(o1>o2) return +1;
                if(o1.equals(o2)) return 0;
                return -1;
            }
        });

输入数组的数字将一个接一个地添加到队列中。然而,当数组[12,4,5,3,8,7]是一个样本输入,打印优先队列的输出是:

MIN:[3.0, 4.0, 5.0, 12.0, 8.0, 7.0]MAX:[12.0, 8.0, 7.0, 3.0, 4.0, 5.0]

我定义的比较器有什么问题吗?提前感谢你的帮助。

共有1个答案

盛柏
2023-03-14

当您迭代PriorityQueue的元素时,这些元素不是完全有序的。唯一可以确定的是,PriorityQueue将强制执行最小和最大元素分别是minu-pqmax-pq优先级队列的第一个元素。

来自PriorityQueue javadocs:

这个队列的头是相对于指定排序的最小元素。

基于此假设,如果使用方法poll(),则可以按顺序打印:

while(!max_pq.isEmpty())
{
    System.out.println(max_pq.poll());
}

投票方式:

检索并删除此队列的头,如果此队列为空,则返回null。

要比较Doubles,应使用Double方法。比较(o1,o2)。此外,您可以使用lambda和方法引用简化比较器,即代替:

PriorityQueue<Double> max_pq = new PriorityQueue<>(new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                if(o1<o2) return +1;
                if(o1.equals(o2)) return 0;
                return -1;
            }
        });

        PriorityQueue<Double> min_pq = new PriorityQueue<>(new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                if(o1>o2) return +1;
                if(o1.equals(o2)) return 0;
                return -1;
            }
        });

您可以使用更优雅、更简单的:

PriorityQueue<Double> max_pq = new PriorityQueue<>(Double::compareTo);
PriorityQueue<Double> min_pq = new PriorityQueue<>((o1, o2) -> Double.compare(o2, o1));

或者,您可以选择TreeSet,而不是PriorityQueue,在那里您可以根据所选的比较器按顺序迭代元素,而无需删除任何元素。

TreeSet<Double> max_pq = new TreeSet<>(Double::compareTo);

TreeSet的另一个好处是,它附带了方法khendingSet()。因此,您不需要保留两个数据结构来保持minmax的顺序,相反,您可以只使用:

  TreeSet<Double> max_pq = new TreeSet<>(Double::compareTo);
   
  max_pq.forEach(System.out::println);
  max_pq.descendingSet().forEach(System.out::println); 
 类似资料:
  • 我定义最大优先级队列如下: 我需要理解这是如何工作的,特别是当1只得到2的索引(而不是4)时? 多谢了。

  • 我有一个,名为,其中包含类型的对象。 您可以在所有车辆上调用该方法。 我要做的是排序,这样车辆被赋予更高的优先级,并被放在队列的前面。 我假设我必须在这里使用一个比较器,但不知道怎么做。

  • 我的问题是:每个节点的优先级是什么?我认为它是最小值的传入边缘的权重,但我不确定。这是真的吗? 第二个问题,当我提取队列的根时,如果这个节点不与任何一个被访问的节点邻接,它将如何工作?

  • 我目前正在尝试实现min heap PQ,但是我在实现的正确性方面遇到了一些问题,我似乎无法找出我做错了什么——它没有输出最低优先级,也没有对它们进行正确排序。 使用以下测试数据: 我得到以下结果: 我希望结果是按升序排列的——起初我认为这可能是因为交换了错误的孩子,但最后一个输出是最大的优先级,所以这没有意义。我花了几个小时试图研究堆优先级队列,但我找不到任何帮助。 以下是CMP要求的更好的代码

  • 注意:我知道可以用比较器创建优先级队列,然后重复调用Add。

  • 考虑下面的优先级类声明<代码>类优先级队列 我的想法: 我能想到的一件事是,这将强制优先级队列使用对象比较器,并且不会提供实现其自定义比较器的能力,因为类的用户可能希望基于某个不同的比较器构建队列。