霍夫曼编码树 - 优先级队列故障

时间:2015-10-05 14:39:03

标签: java priority-queue huffman-code

我试图编写一个程序来计算字符串中每个字符的霍夫曼代码。

这是我的代码::

import java.util.Collections;
import java.util.PriorityQueue;

public class HuffmanCode{
    PriorityQueue<Node> queue = new PriorityQueue<Node>();
    PriorityQueue<Node> queueCopy = new PriorityQueue<Node>();

    public void getCodes(String text) {
        int[] count = countOccurences(text);
        fillQueue(count);
        makeHuffmanTree();
        assignCodes();
        displayCodes();
    }

    public int[] countOccurences(String text) {
        int[] letters = new int[256];
        for(int i = 0; i < text.length(); i++) {
            letters[(int)(text.charAt(i))]++;
        }
        return letters;
    }

    public void fillQueue(int[] count) {
        for(int i = 0; i < count.length; i++) {
            if(count[i] != 0) {
                queue.offer(new Node((char)i, count[i]));
                queueCopy.offer(new Node((char)i, count[i]));
            }
        }
    }

    public void makeHuffmanTree() {
        if(queue.size() > 1) {
            Node node1 = queue.remove();
            Node node2 = queue.remove();
            queue.offer(new Node(node1, node2));
            makeHuffmanTree();
        }
    }

    public void assignCodes() {
        assignCodes(queue.remove(), "");
    }

    public void assignCodes(Node root, String code) {
        if(root.left != null) 
            assignCodes(root.left, code + "0");
        if(root.right!= null) 
            assignCodes(root.right, code + "1");
        if(root.left == null && root.right == null)
            root.code = code + "";
    }

    public void displayCodes() {
        for(Node n: queue)
            System.out.println(n.character + " -> " + n.weight + " -> " + n.code);
    }
}

这里是Node class ::

public class Node implements Comparable<Node>{
    char character;
    int weight;
    Node left;
    Node right;
    String code = "";

    Node(char character, int weight) {
        this.character = character;
        this.weight = weight;
    }

    Node(Node node1, Node node2) {
        weight = node1.weight + node2.weight;
        left = node1;
        right = node2;
    }

        }@Override
    public int compareTo(Node e) {
        if(this.weight < e.weight)
            return -1;
        else if(this.weight == e.weight)
            return 0;
        else
            return 1;
    }
}

如果你调试上面的代码,你会注意到queue中的元素没有正确排序。如果text是&#39;密西西比&#39;,那么queue包含M,i,p,s - 这是错误的(因为,M发生一次,{{ 1}}发生4次,i一次,p发生4次)。它应该是M,p,s,i。

更新

我将s方法替换为:

compareTo

现在,虽然排序与所需的顺序相反,但排序是正确的。这次,当我输入@Override public int compareTo(Node e) { if(this.weight < e.weight) return 1; else if(this.weight == e.weight) return 0; else return -1; } 时,Mississipi包含&#39; i,s,p,M&#39;

1 个答案:

答案 0 :(得分:0)

来自PriorityQueue

的Javadoc
  

此队列的头部是指定排序的最小元素。如果多个元素被绑定为最小值,则头部是这些元素之一 - 关系被任意打破。队列检索操作轮询,删除,查看和元素访问队列头部的元素。

对于PriorityQueue.iterator()

  

public Iterator iterator()   返回此队列中元素的迭代器。迭代器不会以任何特定顺序返回元素。

如果您想要一个已排序的结构,您可以使用TreeSet。