2010-06-15 6 views
4

내 노드 클래스를 비교하기 위해 사용자 지정 비교기를 작성했지만 java 우선 순위 큐가 내 항목을 올바른 순서로 반환하지 않습니다. getF 더블을 반환Java : 사용자 지정 비교기에서 잘못된 순서를 반환하는 PriorityQueue?

public int compare(Node n1, Node n2){ 

    if (n1.getF() > n2.getF()){ 
     return +1; 
    } 
    else if (n1.getF() < n2.getF()){ 
     return -1; 
    } 
    else { // equal 
     return 0; 
    } 
} 

:

여기 내 비교기이다. 그러나 우선 순위 큐에 여러 개의 노드를 삽입 한 후, 나는 사용하여 인쇄 :

결과
while(open.size() > 0) { 
    Node t = (Node)(open.remove()); 
    System.out.println(t.getF()); 
} 

:

6.830951894845301 
6.830951894845301 
6.0 
6.0 
5.242640687119285 
7.4031242374328485 
7.4031242374328485 
8.071067811865476 

이 왜 그런지 어떤 아이디어? 내 비교기가 잘못 되었나요? 감사.

마이크

+0

"Java 우선 순위 큐"는 어떤 실제 Java 클래스입니까 (PriorityQueue를 가정합니다). 어떻게 구성합니까? – Gray

+0

java.util.PriorityQueue, 그렇습니까? – Ceilingfish

+1

귀하의 질문에 대답하지 않지만 귀하의 콤퍼레이터를 단순화 할 수 있다는 것을 알았습니다 : return Double.compare (n1.getF(), n2.getF()); ' –

답변

7

어떻게 그 값을 인쇄하고 있습니까? 당신은 당신이 정렬되지 않은 출력을 받고있을 것이다

for(Node n : queue) { 
System.out.println(n.getF()); 
} 

을하고 있다면 나는 그렇게 잠재적 PriorityQueue에서 반복자가 전체 클래스가하는 같은 순서 보장을 제공합니다 생각하지 않습니다. 주문 보증은 offer, take, poll, peek 및 일부 다른 방법에만 적용됩니다.

http://java.sun.com/javase/6/docs/api/java/util/PriorityQueue.html

+1

맞습니다. 'iterator()'메소드의'PriorityQueue' javadoc에서 : "반복자는 어떤 특정 순서로 요소를 반환하지 않습니다." –

+0

"어떻게 그 값을 인쇄하고 있습니까?".... 질문은 "나는 그들을 사용하여 인쇄합니다 ..."라고 말합니다. – aioobe

+1

iterator를 사용하고 있지 않습니다. 비교 자 comparator = new NodeComparator(); PriorityQueue open = 새 PriorityQueue (INITIAL_SIZE, comparator); 그리고 위의 while 루프. –

4

코드 뭐가 잘못 됐는지 몰라 우선 순위 큐의의 javadoc의 반복자에 특별한 언급이다, 그러나 이것은 나를 위해 작동 :

import java.util.*; 
public class Test { 
    public static void main(String[] args) { 
     PriorityQueue<Node> open = new PriorityQueue<Node>(10, 
       new Comparator<Node>() { 
      @Override 
      public int compare(Node n1, Node n2){ 
       if (n1.getF() > n2.getF()){ 
        return +1; 
       } 
       else if (n1.getF() < n2.getF()){ 
        return -1; 
       } 
       else { // equal 
        return 0; 
       } 
      } 
     }); 

     for (int i = 0; i < 20; i++) 
      open.add(new Node()); 

     while(open.size() > 0) { 
      Node t = (Node)(open.remove()); 
      System.out.println(t.getF()); 
     } 
    } 
} 

class Node { 
    double d = Math.random() * 10; 
    public double getF() { return d; } 
} 

출력 :

0.21442281608773262 
1.9965384843480016 
2.6660026888929824 
2.888889937975976 
3.098932914222398 
3.1059072964534638 
4.193212975907516 
4.296282412431935 
4.3241392173963735 
4.825876226139123 
5.193550353435191 
5.637831708672641 
5.949759449054407 
6.620639629878806 
7.505126870725806 
7.966337123623846 
8.270840212631589 
8.484502118941545 
8.730910327480023 
9.191324325662219 

실수로 getF()이 int 버전의 double을 반환하지 않는지 확인하십시오.


업데이트 : 삽입 후 요소의 순서를 정의하는 데이터를 업데이트 할 수 없습니다. 이 경우 요소를 추출하고 업데이트 한 다음 다시 삽입해야합니다.

+0

클래스 반복기를 사용해 볼 수 있습니까? 정렬되지 않은 출력이 표시되는지 확인하십시오. – Ceilingfish

+0

그러면 주문이 잘못되었습니다. 말이된다. 힙으로 구현 된 경우 제거 할 다음 요소는 모두 알고 있습니다. – aioobe

+0

흠 ... 우선 프리 오 대기열에 노드를 추가 한 다음 노드의 "setF"함수를 사용하여 f 값을 변경합니다. 개체가 삽입 된 후 prio 대기열에서 업데이트되지 않는 값에 대해 뭔가가 있습니까? 프리모 대기열의 노드를 가리키고 있더라도? @Ceilingfish - 내 노드 클래스는 f 값을 -1로 초기화 한 다음 prio 대기열에 삽입 한 다음 f val을 업데이트합니다. 위의 예와 다른 점은 무엇입니까? 그래도 고마워. 기본 논리를 두 번 확인해 줘. 고마워. –

관련 문제