简体   繁体   English

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

[英]Huffman coding tree - Priority queue malfunctioning

I'm trying to write a program for calculating Huffman codes for each character in a string. 我正在尝试编写一个用于计算字符串中每个字符的霍夫曼代码的程序。

Here's my 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);
    }
}

Here's the Node class:: 这是Node类:

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;
    }
}

If you debug the above code, you'll note that the elements in queue are not properly sorted. 如果调试上述代码,则会注意到queue中的元素未正确排序。 If text is 'Mississipi', for example, then queue contains M,i,p,s - which is wrong (because, M occurred once, i occured 4 times, p once and s occured 4 times). 例如,如果text为“ Mississipi”,则queue包含M,i,p,s-这是错误的(因为M发生了一次, i发生了4次, p发生了s发生了4次)。 It should be M,p,s,i. 它应该是M,p,s,i。

UPDATE 更新

I replaced my compareTo method with: 我用以下方法替换了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;
}

Now, though the ordering is opposite to what's required, the sorting is correct. 现在,尽管排序与要求相反,但是排序是正确的。 This time, when I entered Mississipi , the queue contained 'i,s,p,M' 这次,当我进入Mississipiqueue包含“ i,s,p,M”

From the Javadoc for PriorityQueue 从Javadoc for PriorityQueue

The head of this queue is the least element with respect to the specified ordering. 就指定的顺序而言,此队列的头是最小的元素。 If multiple elements are tied for least value, the head is one of those elements -- ties are broken arbitrarily. 如果多个元素的价值最小,那么头就是那些元素之一-领带被任意打破。 The queue retrieval operations poll, remove, peek, and element access the element at the head of the queue. 队列检索操作会轮询,删除,查看和访问元素,以访问队列开头的元素。

And for PriorityQueue.iterator() 对于PriorityQueue.iterator()

public Iterator iterator() Returns an iterator over the elements in this queue. public Iterator iterator()返回对此队列中的元素进行迭代的迭代器。 The iterator does not return the elements in any particular order. 迭代器不会以任何特定顺序返回元素。

If you want a structure which is sorted you can use a TreeSet. 如果要对结构进行排序,则可以使用TreeSet。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM