PriorityQueue.toString неверный порядок элементов
Я пытаюсь сделать очередь приоритетов в java с узлами с наименьшей частотой в приоритете. Однако мой компаратор не работает, и выход очень странный. Я считаю, что мне нужно изменить свой компаратор, но я не уверен, как его изменить.
Вот мой код:
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);
}
}
Выход следующий:
[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].
Однако выход должен быть [z, q, x, j, k, v, b........].
Спасибо заранее!
Ответы
Ответ 1
Вам нужно опросить элементы из PriorityQueue
один за другим. toString
не делает этого.
Поэтому вместо вашего System.out.println(queue);
сделайте следующее:
while(!queue.isEmpty()) {
System.out.println(queue.poll());
}
Причина в том, что PriorityQueue
никогда полностью не сортируется внутри, посмотрите, как куча работает более подробно. Опрос элементов из него фиксирует кучу во время вызовов, поэтому он должен выводить элементы в отсортированном порядке.
Ответ 2
System.out.println(queue)
печатает очередь несортированную. Если вы хотите распечатать реальный порядок очереди, следуйте нижеприведенному коду, который использует опрос, чтобы получить элементы из очереди сверху вниз:
TreeNodeHuffman tn = null;
do{
tn = queue.poll();
if(tn!=null){
System.out.print(tn.key+",");
}
}while(tn != null);
и вы увидите этот результат как ожидалось:
г, д, х, J, K, V, Ь, р, у, г, е, ж, м, и, с, л, д, г, д, с, а, я, о, а, т, е,
Ответ 3
Вы хотите, чтобы более низкая частота повышалась так:
public int compare(TreeNodeHuffman p1, TreeNodeHuffman p2) {
if (p1.frequency < p2.frequency) return 1;
if (p1.frequency > p2.frequency) return -1;
return 0;
}
}
Если вы хотите протестировать его, отправьте его в один пул с потоком и посмотрите порядок обрабатываемых заданий вместо строки или итератора. как говорит doc на http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#iterator%28%29:
Возвращает итератор по элементам в этой очереди. Итератор не возвращает элементы в каком-либо конкретном порядке.
Можно просмотреть http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor%28%29 для быстрого однопоточного пула, чтобы проверить это.