2017-07-19 1 views
2

Ich bin verwirrt. Offer() füllt die Liste in alphabetischer Reihenfolge auf und auch hier werden Großwörter bevorzugt. Wie fülle ich die Liste in der Reihenfolge, in der ich sie eintippe?Warum füllt die Prioritätswarteschlange in Java mit Offer() sie in alphabetischer Reihenfolge auf, während sie auch großgeschriebenen Wörtern Priorität einräumt?

import java.util.*; 
public class Bucky { 

public static void main(String[] args) { 
    PriorityQueue<String> q= new PriorityQueue<String>(); 
    q.offer("first"); 
    q.offer("aecond"); 
    q.offer("zhird"); 

    System.out.printf("%s ",q); 
    System.out.println(); 
    System.out.printf("%s ", q.peek()); 
    System.out.println(); 


} 

} 

o/p = [aecond, zuerst, zhird] aecond


import java.util.*; 
public class Bucky { 

public static void main(String[] args) { 
    PriorityQueue<String> q= new PriorityQueue<String>(); 
    q.offer("first"); 
    q.offer("aecond"); 
    q.offer("Zhird"); 

    System.out.printf("%s ",q); 
    System.out.println(); 
    System.out.printf("%s ", q.peek()); 
    System.out.println(); 


} 

} 

o/p = [Zhird, zuerst, aecond] Zhird

+0

Es ist sortiert nach 'String # compareTo', die" * zwei Strings lexikografisch * "(basierend auf dem Unicode-Wert) vergleicht. Sie müssten Ihre eigene Vergleichszahl eingeben, um die Reihenfolge zu ändern. –

+0

Ich verstehe, warum Großbuchstaben Priorität hat, aber ich bin verwirrt durch die Neuordnung zwischen 'first' und' aecond'. – shmosel

+2

@smossel Das liegt daran, dass 'iterator()' die Elemente nicht in einer bestimmten Reihenfolge durchläuft. Aus der [docs] (https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html): * Der Iterator, der in method iterator() zur Verfügung gestellt wird, kann die Elemente von die Prioritätswarteschlange in einer bestimmten Reihenfolge. Wenn Sie geordnete Traversierungen benötigen, sollten Sie Arrays.sort (pq.toArray()) verwenden * –

Antwort

1

Ich denke, was Sie in Frage stellen, ist die Reihenfolge der Elemente im Array. Das heißt, wenn Sie die Zeile System.out.printf("%s ",q); ausführen, erhalten Sie die Ausgabe [Zhird, first, aecond], und Sie fragen sich, warum das zweite Element im Array first ist, wenn es lexikographisch größer als aecond ist.

Die Antwort liegt in der Struktur der Prioritätswarteschlange. Es ist als binary heap strukturiert und unterliegt der Art, wie ein binärer Heap konstruiert wird.

Ihr Code erstellt den Haufen wie folgt aus:

q.offer("first"); 
q.offer("aecond"); 
q.offer("Zhird"); 

Wenn wir von der Halde als Baum denken, können Sie leichter sehen, was passiert. Der erste Aufruf platziert "first" an der Wurzel des Baums. Die Regeln zum Erstellen eines binären Heapspeichers sagen, dass beim nächsten Aufruf die Zeichenfolge "aecond" an der untersten Stelle ganz links platziert wird und dann die Struktur neu angeordnet wird. Also zuerst haben Sie:

 "first" 
    /
    "aecond" 

Dann arbeiten Sie sich den Baum hinauf. Wenn das Kind kleiner ist als das Elternteil, dann tauschen Sie Eltern und Kind aus. Also in diesem Fall am Ende mit dem Baum:

 "aecond" 
    /
    "first" 

Nun wird die Zeichenfolge "Zhird" kommt. Es wird hinzugefügt, um die niedrigsten, am weitesten links stehenden Position, die nicht belegten ist:

 "aecond" 
    /  \ 
    "first" "Zhird" 

Und es ist Zeit, wieder den Baum neu zu ordnen. "Zhird" lexikographisch kleiner als "aecond", so dass sie ausgetauscht:

 "Zhird" 
    /  \ 
    "first" "aecond" 

Beachten Sie, dass dies immer noch ein gültiger Heap ist. Die untergeordneten Knoten sind größer als das übergeordnete Element.

Die Array-Repräsentation des binären Heaps ist im Grunde nur eine Breite-zuerst-Traversierung des Baums, daher wird dieser Baum als ["Zhird", "first", "aecond"] dargestellt.

Wenn Sie Elemente einzeln aus dem Heap entfernen, erhalten Sie sie in der richtigen Reihenfolge (d. H. "Zhird", "aecond", "first"). Die Array-Repräsentation kann sich jedoch stark von der strikt lexikographischen Reihenfolge unterscheiden, da der Entfernungsprozess den Baum neu anordnet. Wenn Sie das erste Element aus der Warteschlange entfernen würden (z., rufen Sie q.poll), und geben Sie dann das Array aus, Sie würden sehen, dass es zu ["aecond", "first"] umgeordnet wurde.

In meinem Blog, http://blog.mischel.com/2013/09/29/a-better-way-to-do-it-the-heap/, finden Sie eine Erklärung der Heap-Einfüge- und -Entfernungsregeln. Lesen Sie den Folgeartikel http://blog.mischel.com/2013/09/30/a-simple-heap-of-integers/ für eine Implementierung, die Ihnen helfen soll zu verstehen, wie der Baum einem Array zugeordnet ist.

Auch, wenn Sie den Heap in dieser Reihenfolge zu füllen sind:

q.offer("Zhird"); 
q.offer("first"); 
q.offer("aecond"); 

Der Ausgang wäre [Zhird, first, aecond]. Aber wenn Ihre Bestellung war:

Die Ausgabe wäre [Zhird, aecond, first].

+0

Verstanden. Aber wie drucke ich die Liste in der Art, wie ich die Begriffe eintippe? Gibt es einen direkten Weg, oder muss ich es wie einen Baum in Präfix-Reihenfolge drucken? – Anuragkush

+0

@Annagkush: Wenn Sie den Inhalt der Warteschlange in Prioritätsreihenfolge ausgeben möchten, entfernen Sie entweder jedes Element und geben es aus, oder Sie erstellen eine Kopie in einem separaten Array und sortieren es mit demselben Vergleicher, den Sie zum Erstellen verwendet haben die Warteschlange. Wenn Sie den Baum in Präfixreihenfolge durchlaufen, erhalten Sie nicht die gewünschte Reihenfolge. –

0

Wenn Sie wollen den Fall ignorieren, es ist ein einfaches wie:

new PriorityQueue<>(String.CASE_INSENSITIVE_ORDER); 
Verwandte Themen