java sorting printing comparator priority-queue

java - PriorityQueue.toString orden de elementos incorrecto



sorting printing (4)

Estoy tratando de hacer una cola prioritaria en Java con los nodos con la frecuencia más baja en prioridad. Sin embargo, mi comparador no funciona y el resultado es muy extraño. Creo que necesito cambiar mi comparador, pero no estoy seguro de cómo cambiarlo. Aquí está mi código:

public class HuffmanComparator implements Comparator<TreeNodeHuffman> { public int compare(TreeNodeHuffman p1, TreeNodeHuffman p2) { if (p1.frequency < p2.frequency) return -1; if (p1.frequency > p2.frequency) return 1; return 0; } } public class TreeNodeHuffman { public static void main(String[] args) { HuffmanComparator compare = new HuffmanComparator(); TreeNodeHuffman e = new TreeNodeHuffman(''e'', 12702); TreeNodeHuffman t = new TreeNodeHuffman(''t'', 9056); TreeNodeHuffman a = new TreeNodeHuffman(''a'', 8167); TreeNodeHuffman o = new TreeNodeHuffman(''o'', 7507); TreeNodeHuffman i = new TreeNodeHuffman(''i'', 6966); TreeNodeHuffman n = new TreeNodeHuffman(''a'', 6749); TreeNodeHuffman s = new TreeNodeHuffman(''s'', 6327); TreeNodeHuffman h = new TreeNodeHuffman(''h'', 6094); TreeNodeHuffman r = new TreeNodeHuffman(''r'', 5987); TreeNodeHuffman d = new TreeNodeHuffman(''d'', 4253); TreeNodeHuffman l = new TreeNodeHuffman(''l'', 4025); TreeNodeHuffman c = new TreeNodeHuffman(''c'', 2782); TreeNodeHuffman u = new TreeNodeHuffman(''u'', 2758); TreeNodeHuffman m = new TreeNodeHuffman(''m'', 2406); TreeNodeHuffman w = new TreeNodeHuffman(''w'', 2360); TreeNodeHuffman f = new TreeNodeHuffman(''f'', 2228); TreeNodeHuffman g = new TreeNodeHuffman(''g'', 2015); TreeNodeHuffman y = new TreeNodeHuffman(''y'', 1974); TreeNodeHuffman p = new TreeNodeHuffman(''p'', 1929); TreeNodeHuffman b = new TreeNodeHuffman(''b'', 1492); TreeNodeHuffman v = new TreeNodeHuffman(''v'', 978); TreeNodeHuffman k = new TreeNodeHuffman(''k'', 772); TreeNodeHuffman j = new TreeNodeHuffman(''j'', 153); TreeNodeHuffman x = new TreeNodeHuffman(''x'', 150); TreeNodeHuffman q = new TreeNodeHuffman(''q'', 95); TreeNodeHuffman z = new TreeNodeHuffman(''z'', 74); PriorityQueue<TreeNodeHuffman> queue = new PriorityQueue<TreeNodeHuffman>(26, compare); queue.add(e); queue.add(t); queue.add(a); queue.add(o); queue.add(i); queue.add(n); queue.add(s); queue.add(h); queue.add(r); queue.add(d); queue.add(l); queue.add(c); queue.add(u); queue.add(m); queue.add(w); queue.add(f); queue.add(g); queue.add(y); queue.add(p); queue.add(b); queue.add(v); queue.add(k); queue.add(j); queue.add(x); queue.add(q); queue.add(z); System.out.println(queue); } }

La salida es la siguiente: [z, k, q, g, v, x, u, d, f, y, b, m, j, i, c, e, s, o, w, a, r, h , p, t, l, a]. Sin embargo, la salida debe ser [z, q, x, j, k, v, b ........]. ¡Gracias por adelantado!


Debe sondear los elementos de PriorityQueue uno por uno. toString no hace eso.

Entonces, en lugar de su System.out.println(queue); hacer esto:

while(!queue.isEmpty()) { System.out.println(queue.poll()); }

La razón es que PriorityQueue nunca está completamente ordenado internamente, consulte cómo funciona un montón para obtener más detalles. El sondeo de elementos desde él corrige el montón durante las llamadas, por lo tanto, debería mostrar los elementos en orden ordenado.


Desea que la frecuencia más baja aumente, entonces:

public int compare(TreeNodeHuffman p1, TreeNodeHuffman p2) { if (p1.frequency < p2.frequency) return 1; if (p1.frequency > p2.frequency) return -1; return 0; } }

Si desea probarlo, envíelo a un único grupo de subprocesos y vea el orden de los trabajos que se procesan en lugar de en cadena o iterador. como dice el documento en http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#iterator%28%29 :

Devuelve un iterador sobre los elementos en esta cola. El iterador no devuelve los elementos en ningún orden en particular.

Puede ver http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor%28%29 para obtener un grupo de subprocesos rápidos para probar esto.


La respuesta de @Thomas funciona.

Mi enfoque es producir el mismo resultado sin vaciar realmente la cola . Entonces, en su lugar, creé un contenedor sobre PriorityQueue e implementé next() y hasNext() para ello. Además, para simular exactamente el comportamiento de la cola de prioridad, extend AbstractQueue y delegue llamadas a métodos como offer , peek , poll y size través del objeto PriorityQueue.

priorityQueueObject.methodName()

Descargo de responsabilidad: esto cuesta copiar toda la cola en una lista y ordenarla por encima.

public class MyPriorityQueue<E extends Comparable<T>, T> extends AbstractQueue<E> { Integer arrOfInts[] = { 11, 7, 15, 10, 2, 1, 4, 5, 7, 2, 18, 1, 19}; PriorityQueue<E> pq = new PriorityQueue<>(); public static void main(String[] args) { MyPriorityQueue mpq = new MyPriorityQueue<>(); mpq.addAll(Arrays.asList(arrOfInts)); //Using iterator Iterator it = mpq.iterator(); System.out.println("The internal priority queue:" + mpq.pq); System.out.println("Using Iterator:"); while(it.hasNext()) { System.out.print(it.next() + ", "); } System.out.println("/nUsing simple system out println:"); System.out.println(mpq); System.out.println("Using foreach: "); for(Object o : mpq) { System.out.print(o + ", "); } } @Override public boolean offer(E arg0) { return pq.offer(arg0); } @Override public E peek() { return pq.peek(); } @Override public E poll() { return pq.poll(); } @Override public Iterator<E> iterator() { ArrayList<E> list = new ArrayList(Arrays.asList(pq.toArray())); Collections.sort(list, null); return new Iterator<E>() { @Override public boolean hasNext() { return !list.isEmpty(); } @Override public E next() { assert (hasNext()); return list.remove(0); } }; } @Override public int size() { return pq.size(); } }

huellas dactilares:

The internal priority queue:[1, 2, 1, 7, 5, 2, 4, 11, 7, 10, 18, 15, 19] Using Iterator: 1, 1, 2, 2, 4, 5, 7, 7, 10, 11, 15, 18, 19, Using simple system out println: [1, 1, 2, 2, 4, 5, 7, 7, 10, 11, 15, 18, 19] Using foreach: 1, 1, 2, 2, 4, 5, 7, 7, 10, 11, 15, 18, 19,


System.out.println(queue) está imprimiendo la cola sin clasificar. Si desea imprimir el orden real de la cola, siga el siguiente código que utiliza sondeo para obtener los elementos de la cola de arriba a abajo:

TreeNodeHuffman tn = null; do{ tn = queue.poll(); if(tn!=null){ System.out.print(tn.key+","); } }while(tn != null);

y verá esta salida como se esperaba:

z, q, x, j, k, v, b, p, y, g, f, w, m, u, c, l, d, r, h, s, a, i, o, a, t, mi,