添加到 PriorityQueue 的对象不按其优先级排序

发布于 2024-10-27 23:25:05 字数 1637 浏览 1 评论 0原文

我正在尝试使用 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 应该是 [cat,neat,need]
关于为什么会发生这种情况有什么提示吗?

I'm trying to implement a heap using a PriorityQueue as follows:

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());
}

Where I've defined Node as as private class inside the same class that holds the above method. Node is defined as:

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;}
}

However, when I add nodes to the PriorityQueue, they are not ordered by frequency. Based on output from my println statements, the correct values are returned by Node.compareTo(). For example, given the dataset:

  • name, frequency
  • need, 3
  • cat, 1
  • neat, 2

My code produces:
// add need
[need]
// add cat
cat < need
[cat, need]
// add neat
neat > cat
[cat, need, neat]
when the PriorityQueue should be [cat, neat, need]
Any tips as to why this is happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

‘画卷フ 2024-11-03 23:25:05

迭代器 < 的顺序code>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

The order from an iterator for PriorityQueue is undefined; the order when calling poll() should be the comparator ordering. From the API spec,

iterator() Returns an iterator over the elements
in this queue. The iterator does not
return the elements in any particular
order.

If what you really need is a sorted set, use SortedSet OR put things into a collection and use Collections.sort(). If, however, you really need a pqueue, here's my example fix:

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;}
  }

}

Gives:

[need]
cat < need
[cat, need]
neat > cat
[cat, need, neat]
In order now:
neat < need
cat
neat
need
短叹 2024-11-03 23:25:05

PriorityQueues 在“及时”的基础上工作。如果你只显示它们的内容,内容不会按顺序排列;它们在一堆中(既然你提到了,我想你会知道这一点。)无论如何,为了让内容按顺序排列,你必须使用 i poll() 一次将这些项目取出一个。

PriorityQueues work on a "just in time" basis. If you just display their contents, the contents are not going to be in sorted order; they're in a heap (which, since you mentioned, I think you'd know about.) Anyway, to get the contents in order, you have to pull the items off one at a time with i poll().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文