【问题标题】:Objects added to a PriorityQueue are not ordered by their priority添加到 PriorityQueue 的对象不按优先级排序
【发布时间】:2011-07-24 22:45:41
【问题描述】:

我正在尝试使用 PriorityQueue 实现堆,如下所示:

PriorityQueue<Node> heap = new PriorityQueue<Node>();
Set<String> allWords = codebook.getAllWords();
for(String word : allWords)
{
    heap.add(new Node(word, codebook.getProbability(word)));
    System.out.println(heap.toString());
}

我将 Node 定义为包含上述方法的同一类中的私有类。节点定义为:

private static class Node implements Comparable
{
    protected Node left;
    protected Node right;
    protected String name;
    protected double frequency;
    public Node(String n, double f)
    {
        name = n;
        frequency = f;
    }
    public Node(double f, Node l, Node r)
    {
        frequency = f;
        left = l;
        right = r;
    }

    @Override
    public int compareTo(Object arg0) 
    {
        Node other = (Node)(arg0);
        if(this.frequency < other.frequency)
        {
            System.out.println(name + " < " + other.name);
            return -1;
        }
        else if(this.frequency > other.frequency)
        {
            System.out.println(name + " > " + other.name);
            return 1;
        }
        System.out.println(name + " is equal to " + other.name);
        return 0;
    }

    public String toString()
    {return name;}
}

但是,当我将节点添加到 PriorityQueue 时,它​​们不是按频率排序的。根据我的 println 语句的输出,Node.compareTo() 返回了正确的值。例如,给定数据集:

  • 名称、频率
  • 需要,3
  • 猫,1
  • 整洁,2

我的代码产生:
// 添加需求
[需要]
// 添加猫
猫 [猫,需要]
// 添加整洁
整洁 > 猫
[猫,需要,整洁]​​
当 PriorityQueue 应该是 [猫,整洁,需要]
关于为什么会发生这种情况的任何提示?

【问题讨论】:

    标签: java heap priority-queue compareto


    【解决方案1】:

    来自iterator for PriorityQueue 的订单未定义;调用poll() 时的顺序应该是比较器的顺序。根据 API 规范,

    iterator() 返回元素的迭代器 在这个队列中。迭代器不 返回任何特定的元素 顺序。

    如果您真正需要的是有序集合,请使用SortedSet 或将内容放入集合并使用Collections.sort()。但是,如果你真的需要一个 pqueue,这是我的修复示例:

    import java.util.HashMap;
    import java.util.Map;
    import java.util.PriorityQueue;
    import java.util.Set;
    
    
    public class TestPriorityQueue 
    {
      static Map<String,Double> codebook = new HashMap<String, Double>();
      static {
        codebook.put("need", 3.0);
        codebook.put("cat", 1.0);
        codebook.put("neat", 2.0);
      }
    
      public static void main(String[] args)
      {
        test();
      }
    
      public static void test() {
        PriorityQueue<Node> heap = new PriorityQueue<Node>();
        Set<String> allWords = codebook.keySet();
        for (String word : allWords) {
          heap.add(new Node(word, codebook.get(word)));
          System.out.println(heap.toString());
        }
    
        System.out.println("In order now:");
        while(!heap.isEmpty()) {
          System.out.println(heap.poll());
        }
      }
    
      private static class Node implements Comparable<Node>
      {
          protected Node left;
          protected Node right;
          protected String name;
          protected double frequency;
          public Node(String n, double f)
          {
              name = n;
              frequency = f;
          }
          public Node(double f, Node l, Node r)
          {
              frequency = f;
              left = l;
              right = r;
          }
    
          @Override
          public int compareTo(Node arg0) 
          {
              if(this.frequency < arg0.frequency)
              {
                  System.out.println(name + " < " + arg0.name);
                  return -1;
              }
              else if(this.frequency > arg0.frequency)
              {
                  System.out.println(name + " > " + arg0.name);
                  return 1;
              }
              System.out.println(name + " is equal to " + arg0.name);
              return 0;
          }
    
          public String toString()
          {return name;}
      }
    
    }
    

    给予:

    [need]
    cat < need
    [cat, need]
    neat > cat
    [cat, need, neat]
    In order now:
    neat < need
    cat
    neat
    need
    

    【讨论】:

    • 从以下行生成输出:System.out.println(heap.toString());在第一个代码块中。我看到 toString() 像迭代器一样返回一个字符串表示形式。我将其更改为使用 poll() 打印,输出看起来正确 - 非常感谢!
    • @user681219:欢迎来到 StackOverflow...如果它正确回答了您的问题,请不要忘记接受答案...
    【解决方案2】:

    PriorityQueues 在“及时”的基础上工作。如果只是显示它们的内容,则内容不会按排序顺序排列;它们在一堆(正如你提到的,我想你应该知道的。)无论如何,为了让内容井井有条,你必须使用 i poll() 一次拉出一个项目。

    【讨论】:

    • 我确实知道它们在堆中,但(错误地)假设 toString() 会按排序顺序打印 PriorityQueue。谢谢你纠正我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2018-11-03
    相关资源
    最近更新 更多