gpt4 book ai didi

java - Java 中的霍夫曼树

转载 作者:太空宇宙 更新时间:2023-11-04 07:37:19 25 4
gpt4 key购买 nike

我的霍夫曼树代码有问题。在主要方法中,我输入一个符号字符串,还输入一个包含符号频率的整数数组。它应该打印出每个符号及其霍夫曼代码,但我认为它是错误的......

这是代码:

 package huffman;

import java.util.*;

abstract class HuffmanTree implements Comparable<HuffmanTree> {
public final int frequency; // the frequency of this tree
public HuffmanTree(int freq) { frequency = freq; }

// compares on the frequency
public int compareTo(HuffmanTree tree) {
return frequency - tree.frequency;
}
}

class HuffmanLeaf extends HuffmanTree {
public final char value; // the character this leaf represents

public HuffmanLeaf(int freq, char val) {
super(freq);
value = val;
}
}

class HuffmanNode extends HuffmanTree {
public final HuffmanTree left, right; // subtrees

public HuffmanNode(HuffmanTree l, HuffmanTree r) {
super(l.frequency + r.frequency);
left = l;
right = r;
}
}

public class Huffman {
// input is an array of frequencies, indexed by character code
public static HuffmanTree buildTree(int[] charFreqs, char[] test2) {
PriorityQueue<HuffmanTree> trees = new PriorityQueue<HuffmanTree>();
// initially, we have a forest of leaves
// one for each non-empty character
for (int i = 0; i < charFreqs.length; i++)
if (charFreqs[i] > 0)
trees.offer(new HuffmanLeaf(charFreqs[i], test2[i]));

assert trees.size() > 0;
// loop until there is only one tree left
while (trees.size() > 1) {
// two trees with least frequency
HuffmanTree a = trees.poll();
HuffmanTree b = trees.poll();

// put into new node and re-insert into queue
trees.offer(new HuffmanNode(a, b));
}
return trees.poll();
}

public static void printCodes(HuffmanTree tree, StringBuffer prefix) {
assert tree != null;
if (tree instanceof HuffmanLeaf) {
HuffmanLeaf leaf = (HuffmanLeaf)tree;

// print out character, frequency, and code for this leaf (which is just the prefix)
System.out.println(leaf.value + "\t" + leaf.frequency + "\t" + prefix);

} else if (tree instanceof HuffmanNode) {
HuffmanNode node = (HuffmanNode)tree;

// traverse left
prefix.append('0');
printCodes(node.left, prefix);
prefix.deleteCharAt(prefix.length()-1);

// traverse right
prefix.append('1');
printCodes(node.right, prefix);
prefix.deleteCharAt(prefix.length()-1);
}
}

public static void main(String[] args) {
//Symbols:
String str = "12345678";
char[] test2 = str.toCharArray();
//Frequency (of the symbols above):
int[] charFreqs = {36,18,12,9,7,6,5,4};


// build tree
HuffmanTree tree = buildTree(charFreqs,test2);

// print out results
System.out.println("SYMBOL\tFREQ\tHUFFMAN CODE");
printCodes(tree, new StringBuffer());
}
}

我得到的输出是:

SYMBOL  FREQ    HUFFMAN CODE
1 36 0
3 12 100
6 6 1010
5 7 1011
2 18 110
4 9 1110
8 4 11110
7 5 11111

这很奇怪,例如符号 7 应该是:11110,符号 8 应该是:11111

你能帮我吗?

最佳答案

位模式的分配与代码的最优性无关。你的任务将会很好地完成。这并没有什么奇怪的。您也可以对 2:110、3:100 或 4:1110、5:1011 表示担忧,但这些也很好。

对代码施加顺序的唯一原因是减少将代码从压缩器传送到解压缩器所需的位数。您可以发送每个符号的代码长度,而不是发送代码,只要代码的长度在两侧构造相同即可。

在这种情况下,方法通常是将代码按数字顺序分配给排序的符号列表。那么,如果符号 7 的分配顺序是这样的话,那么符号 7 的代码“值”确实会低于符号 8。

对于您的示例,这样的规范代码将是:

1: 1 - 0
2: 3 - 100
3: 3 - 101
4: 4 - 1100
5: 4 - 1101
6: 4 - 1110
7: 5 - 11110
8: 5 - 11111

您只需获取长度并在相同长度内对符号进行排序即可。然后分配从 0 开始并递增的代码,随着长度的增加,在末尾添加位。

请注意,这是一个不寻常的示例,其中符号顺序也是频率顺序。通常情况并非如此。

关于java - Java 中的霍夫曼树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16658419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com