0
我想写一个程序来计算字符串中每个字符的霍夫曼代码。霍夫曼编码树 - 优先队列故障
这里是我的代码::
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
类::
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
是'Mississipi',则queue
包含M,i,p,s-这是错误的(因为,M
发生一次,i
发生4次,p
一次,并且s
发生4次)。它应该是M,P,S,I。
UPDATE
我取代了我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
,所述queue
包含“I,S,P,M”
我已更新我的问题。请看一下。 – Saud
@Saud“虽然排序与所需要的相反,”您正在返回与通常使用的符号相反的符号。认为'sign(this.weight - e.weight)'或'Integer.compare(this.weight,e.weight)' –