Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个优先队列有什么问题? marge=新的优先级队列(10,新的比较器(){ @凌驾 公共整数比较(节点1、节点2) { 如果(f(节点1)>f(节点2)) 返回1; 其他的 返回-1; } });_Java - Fatal编程技术网

Java 这个优先队列有什么问题? marge=新的优先级队列(10,新的比较器(){ @凌驾 公共整数比较(节点1、节点2) { 如果(f(节点1)>f(节点2)) 返回1; 其他的 返回-1; } });

Java 这个优先队列有什么问题? marge=新的优先级队列(10,新的比较器(){ @凌驾 公共整数比较(节点1、节点2) { 如果(f(节点1)>f(节点2)) 返回1; 其他的 返回-1; } });,java,Java,我声明了一个PQ来存储一些节点,我想根据f值以非递减顺序存储节点。函数f(Node Node)用于计算节点的f值。所以我覆盖了比较器,但现在我发现一些f值较大的节点被放置在队列中f值较小的节点之前,我检查了所有节点,但仍然找不到哪里出了问题,我假设这可能是PQ声明的问题。有人能帮我吗?提前谢谢 您是否也覆盖了equals()?正如报告中指出的那样 当使用比较器时,应谨慎使用,比较器能够对排序集(或排序映射)施加与等于不一致的排序。假设一个带有显式比较器c的排序集(或排序映射)与从集合S中提取的元

我声明了一个PQ来存储一些节点,我想根据f值以非递减顺序存储节点。函数f(Node Node)用于计算节点的f值。所以我覆盖了比较器,但现在我发现一些f值较大的节点被放置在队列中f值较小的节点之前,我检查了所有节点,但仍然找不到哪里出了问题,我假设这可能是PQ声明的问题。有人能帮我吗?提前谢谢

您是否也覆盖了
equals()
?正如报告中指出的那样

当使用比较器时,应谨慎使用,比较器能够对排序集(或排序映射)施加与等于不一致的排序。假设一个带有显式比较器c的排序集(或排序映射)与从集合S中提取的元素(或键)一起使用。如果c对S施加的顺序与equals不一致,则排序集(或排序映射)的行为将“奇怪”。特别是排序集(或排序映射)将违反集合(或映射)的一般约定,它的定义是平等的

还要注意,当您重写
equals()
时,还必须重写
hashCode()
,如中所述

即使
PriorityQueue
不是一个(排序的)集合,正如注释中所指出的,如果您想切换数据结构,使其能够以特定的顺序进行迭代(队列不能,排序的集合可以),那么最好使用
compare()
equals()
hashCode()
完全按照建议实施。

请参阅。我引述:

方法Iterator()中提供的迭代器不保证以任何特定顺序遍历PriorityQueue的元素。如果需要有序遍历,请考虑使用数组。排序(pq.toAlayle())。< /代码> 


可以保证的是,根据比较器,最上面的元素是最小的。

正如@izomorphius所说,PriorityQueue并不保证完全排序,只是头部总是最小的

如果您想要完整订单-您可能需要选择以下可能性之一:

  • 使用-但请注意,它不允许重复。此外,正如@JoonasPulakka所述,这里您可能还需要覆盖
    equals()
    hashCode()
  • 使用a-填充它[unordered],然后使用根据比较器对其进行排序
  • 使用数组[
    节点[]
    ],填充它[无序],然后使用根据比较器对其进行排序
  • 编辑:
    您编辑的比较器不强制执行完全排序,因此使用它的结果未定义:
    a
    b
    为两个
    节点
    s,使得
    f(a)==f(b)

    但各州:

    实现者必须确保sgn(compare(x,y))==-sgn(compare(y, x) )适用于所有x和y

    因此,使用这个[编辑的]比较器的结果是未定义的

    EDIT2:
    你的评论表明你正在寻找第二个标准——“增加时间”。您可以将另一个字段
    long timestamp
    添加到
    节点
    对象中,并在
    比较器中
    基于此字段返回结果,当且仅当
    f(node1)==f(node2)
    。这将保证一致性,并实现所需的功能


    注意:当您第一次向队列中添加元素[或者当创建对象时,如果它是一个选项]。

    据我所知,
    PriorityQueue
    不使用
    equals()
    ,并且它不是
    集。你能指出一个关于
    PriorityQueue
    s的文档吗?
    通常是这样,但**不是严格要求**(比较(x,y)==0)=(x.equals(y))。
    @amit:不需要,但肯定推荐:
    一般来说,任何违反此条件的比较器都应该清楚地指出这一事实。
    特别是,如果您碰巧将数据结构从不严格要求一致等于和比较的内容切换到确实需要一致等于和比较的内容,您会发现您的数据项已经做了推荐的事情。
    equals()
    hashCode()
    也是一样的:在很多情况下,只要重写其中一个,一切都可以正常工作,但稍后它就会咬到你。我同意如果这是比较的自然顺序-
    compareTo()
    方法,它是从继承的,但对于自定义比较器,情况通常不是这样。在任何情况下,这都不能解释为什么他的元素是无序的。当您迭代地从中弹出元素时是“无序”吗?还是仅在构造上?我没有使用迭代器遍历队列,在我的程序中,我只是使用for循环打印出队列中每个节点的f值。它的工作原理与迭代器相同吗?它在内部使用迭代器。正如我所说的,唯一可以保证的是顶部是最小的元素。因此,您可以做的是执行一个循环,在该循环中,您进行查看,然后进行轮询,直到队列中有元素。当您这样做时,您将看到您按顺序查看元素。@tonyaziten注意,在这种情况下,即使是最上面的元素也不能保证,因为您的比较器不符合javadocs中规定的要求。请注意,如果比较器是“正确”的,则只有迭代地取出优先级队列的头并将其打印出来,您才能看到“正确”的顺序。@amit事实上他的代码已经更改,我相信比较器的第一个版本确实符合要求。@izomorphius:我知道,I v
    fringe = new PriorityQueue<Node>(10,new Comparator<Node>(){
                @Override
                public int compare(Node node1,Node node2)
                {
                    if (f(node1)>f(node2))
                        return 1;
                    else
                        return -1;
                }
            });
    
    compare(a,b) == compare(b,a) == -1