【问题标题】:Min Priority Queue and Max Priority Queue not sorting correctly [duplicate]最小优先级队列和最大优先级队列未正确排序[重复]
【发布时间】:2020-11-25 18:28:25
【问题描述】:

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

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] 是样本输入并且打印优先级队列的输出为:

最小值:[3.0, 4.0, 5.0, 12.0, 8.0, 7.0] 最大值:[12.0、8.0、7.0、3.0、4.0、5.0]

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

【问题讨论】:

    标签: java priority-queue


    【解决方案1】:

    当您遍历PriorityQueue 的元素时,这些元素不是完全 有序的。您唯一可以确定的是,PriorityQueue 将强制 smallestbiggest 元素是 @ 的 first 元素分别为 987654324@ 和 max_pq 优先级队列。

    来自PriorityQueuejavadocs:

    这个队列的头是相对于 指定的顺序。

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

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

    投票方式:

    获取并移除此队列的头部,如果此则返回 null 队列是空的。

    为了比较Doubles,您应该使用方法Double.compare(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 的另一个好处是它带有 descendingSet() 方法。因此,您不需要保留两个数据结构来同时保留minmax 的顺序,而是只需:

      TreeSet<Double> max_pq = new TreeSet<>(Double::compareTo);
       
      max_pq.forEach(System.out::println);
      max_pq.descendingSet().forEach(System.out::println); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 2014-08-05
      相关资源
      最近更新 更多