Reputation: 43
I want to implement an function which gives me a binary code for each char in a huffman tree.
To implement the function i tried traversing the table by using a recursive function. However i don't know how to fill the result the binary code for each char so that the function returns an array of struct with all the chars and binary codes
I hope someone can point me in the right direction.
Thanks ahead!
Upvotes: 3
Views: 3397
Reputation: 986
I would start by making compute_code_table
recursive, this allows you to easily traverse the tree.
Secondly, it helps for every task or assignment to search online for some sources which explain (in pseudo-code or not) how to do your specific task. In this case, this yields the following explanation:
To generate a huffman code you traverse the tree to the value you want, outputing a 0 every time you take a lefthand branch, and a 1 every time you take a righthand branch. (normally you traverse the tree backwards from the code you want and build the binary huffman encoding string backwards as well, since the first bit must start from the top).
In C, this could be implemented as such:
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;
}
}
Then you only have to call compute_code_table_for_node(tree, node, tree->head, 0)
for every node
in the tree
.
This piece of code won't work for your specific case, so you will have to rewrite it.
Upvotes: 2
Reputation: 3418
Ok, let's see a possible solution:
#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");
}
}
}
Basically the idea is to have a table which is filled at every leaf. While doing the recursion we pass the current node, the table and the current code. If we are at a leaf we just store the code in the table, otherwise we need to perform the recursion: increase the code length, add a 0 in the least significant bit and do the left branch, then change that 0 to a 1 and do the right branch.
Upvotes: 3