我想实现一个函数,它为huffman树中的每个char提供二进制代码。
实现我尝试使用递归函数遍历表的函数。但是,我不知道如何为每个char填充二进制代码的结果,以便函数返回包含所有字符和二进制代码的struct数组
我希望有人能指出我正确的方向。
提前致谢!
答案 0 :(得分:3)
好的,让我们看一个可能的解决方案:
#include <stdint.h>
typedef struct code {
size_t code_length;
uint32_t code;
} code;
void compute_code_table(tree_t node, code *t, code c)
{
if (node->left == NULL)
t[node->letter] = c;
else {
c.code_length++;
c.code <<= 1;
compute_code_table(node->left, t, c);
c.code += 1;
compute_code_table(node->right, t, c);
}
}
void code_print(code *c)
{
size_t n = c->code_length;
while (n --> 0)
putchar('0' + ((c->code >> n) & 1));
}
int main(void)
{
tree_t root = fixed_tree();
code table[256] = { 0 };
code c = { 0 };
compute_code_table(root, table, c);
for (size_t i = 0; i < 256; ++i) {
if (table[i].code_length) {
printf("%c\t", i);
code_print(table + i);
printf("\n");
}
}
}
基本上,我们的想法是在每片叶子上放一张桌子。在进行递归时,我们传递当前节点,表和当前代码。如果我们在一个叶子,我们只是将代码存储在表中,否则我们需要执行递归:增加代码长度,在最低有效位中添加0并执行左分支,然后将该0更改为1并且做正确的分支。
答案 1 :(得分:2)
我首先使compute_code_table
递归,这样可以轻松遍历树。
其次,它有助于每个任务或任务在线搜索某些来源,这些来源解释(伪代码或非伪代码)如何执行您的特定任务。在这种情况下,这会产生以下解释:
要生成霍夫曼代码,请将树遍历到您的值 想要,每次拿左手分支输出0,输出1 每次你采取右手分支。 (通常你会穿越 树从您想要的代码向后,并构建二进制霍夫曼 编码字符串也是向后的,因为第一位必须从 顶部)。
在C中,这可以这样实现:
int compute_code_table_for_node(tree_t tree, node_t target_node, node_t current_node, int code_table) {
// Check for target
if ( current_node == target_node ) {
// Found target
return code_table;
}
// Check if end-node
if ( current_node->left == NULL && current_node->right == NULL ) {
// Is an end node
return -1;
}
// Try left
int left = compute_code_table_for_node(tree, target_node, current_node->left, code_table << 1 + 0);
// Try right
int right = compute_code_table_for_node(tree, target_node, current_node->right, code_table << 1 + 1);
// Find which path was taken
if ( left == -1 ) {
// Left path didn't find it, so it must be the right path:
return code_table << 1 + 1;
} else {
// Left path found it
return code_table << 1 + 0;
}
}
然后,您只需为compute_code_table_for_node(tree, node, tree->head, 0)
中的每个node
致电tree
。
这段代码不适用于您的特定情况,因此您必须重写它。