我正在尝试创建一个霍夫曼树,我读到的问题对我来说很奇怪,它如下:
鉴于以下数据结构:
struct huffman { unsigned char sym; /* symbol */ struct huffman *left, *right; /* left and right subtrees */ };
编写一个以二进制文件名称为唯一参数的程序, 假设原子(小学的)构建该文件的霍夫曼树 符号)是8位无符号字符,并打印树以及 字典。
分配必须使用其他任何东西 malloc(),可以使用qsort()完成排序。
这让我感到困惑的是,编写一个程序来创建一个霍夫曼树,我们只需要做以下事情:
Farray[]={.......}
)现在的问题是:我们为什么以及在哪里需要那些未签名的char数据? (这个问题想要什么类型的unsigned char数据,我认为只有频率足以显示一个Huffman树)?
答案 0 :(得分:2)
如果你纯粹想要显示树的形状,那么是的,你只需要构建它。但是,对于任何用途,您需要知道每个节点代表的原始符号。
想象一下你的输入符号是[ABCD]。想象中的霍夫曼树/字典可能如下所示:
( )
/ \ A = 1
( ) (A) B = 00
/ \ C = 010
(B) ( ) D = 011
/ \
(C) (D)
如果您不存储sym
,它看起来像这样:
( )
/ \ A = ?
( ) ( ) B = ?
/ \ C = ?
( ) ( ) D = ?
/ \
( ) ( )
不是很有用,是吗?
编辑2:计划中缺少的步骤是步骤0:从文件构建频率数组(不知怎的,我错过了你不需要实际编码文件)。这不是实际的霍夫曼算法本身的一部分,我找不到一个合适的例子来链接,所以这里有一个粗略的想法:
FILE *input = fopen("inputfile", "rb");
int freq[256] = {0};
int c;
while ((c = fgetc(input)) != EOF)
freq[c]++;
fclose(input);
/* do Huffman algorithm */
...
现在,仍然需要改进,因为它既不使用malloc()
也不使用文件名作为参数,但它不是我的作业;)
答案 1 :(得分:0)
我这样做了一段时间,但我认为生成的“词典”需要编码数据,而“树”用于解码。当然,你总是可以从另一个构建一个。
在解码时,您遍历树(左/右,根据连续的输入位),当您点击终端节点(空指针)时,节点中的'sym'是输出值。
答案 2 :(得分:0)
通常数据压缩分为两大步骤;给出了一个数据流:
在实践中它比这更复杂,因为树涉及到,但主要目的始终是构建字典。
有一个完整的tutorial here。