huff_node *create_huff_tree_from_frequency(unsigned long long frequencyArray[256]) { huff_node *nodes[256]; for (int i = 0; i < 256; i++) { nodes[i] = NULL; nodes[i] = create_huff_node(i, frequencyArray[i], NULL); } /*for(int i = 0; i<255; i++){ assert(nodes[i]->char_number == i+1); } assert(nodes[255]->char_number == 0); */ // Unfortunately, the old queue-based construction system was just incorrect // It gave wrong trees // Perform 255 node merges for (int firstIndex = 0; firstIndex < 255; firstIndex++) { qsort(nodes+firstIndex, 256-firstIndex, sizeof (huff_node *), huff_node_frequency_comparer); huff_node* left_child = nodes[firstIndex]; huff_node* right_child = nodes[firstIndex+1]; huff_node* new_parent = create_parent_node(left_child, right_child); nodes[firstIndex+1] = new_parent; } huff_node *root = nodes[255]; generate_encoding_tree(root); return root; }
huff_node *create_parent_node(huff_node *left_child, huff_node *right_child) { //create huff_node huff_node *parent = create_huff_node( -1, left_child->frequency + right_child->frequency, NULL); set_children_nodes(parent, left_child, right_child); parent->lowest_value = min(left_child->lowest_value, right_child->lowest_value); return parent; }
static huff_node_t * build_huff_tree(unsigned long int *frequency) { int i; queue_t *queue = create_queue(sizeof(huff_node_t)); for(i = 0; i < CHARS_NUM; i++) { if (frequency[i] > 0) queue_insert(queue, frequency[i], create_huff_node((char)(i - CHARS_NUM/2), frequency[i], NULL, NULL)); } huff_node_t *left = NULL, *right = NULL; do { left = (huff_node_t*)queue_pop(queue); right = (huff_node_t*)queue_pop(queue); if (!right || !left) break; queue_insert(queue, left->frequency + right->frequency, create_huff_node((char)0, left->frequency + right->frequency, left, right)); } while (left && right); return left; }
void insert_encoded_node(huff_node *root, huff_node *node){ int length = strlen(node->encoding); char *encoding = node->encoding; huff_node *current = root; for(int i = 0; i < length; i++){ if(encoding[i] == '0'){ if(current->left_child == 0){ if(i == length-1){ current->left_child = node; return; } else{ huff_node *left_child = create_huff_node(-1, -1,create_string_from_cat(current->encoding, "0")); set_left_child(current, left_child); current = left_child; continue; } } else{ current = current->left_child; } } //next character is a 1 else{ if(current->right_child == 0){ if(i == length-1){ current->right_child = node; return; } else{ huff_node *right_child = create_huff_node(-1, -1,create_string_from_cat(current->encoding, "1")); set_right_child(current, right_child); current = right_child; continue; } } else{ current = current->right_child; } } } }
huff_node *create_huff_tree_from_encoding(char **encoding) { huff_node *nodes[256]; for (int i = 0; i < 256; i++) { nodes[i] = NULL; // All node encodings have to be malloc'd (they're freed on destruct) char *node_encoding = xmalloc(strlen(encoding[i]) + 1); strcpy(node_encoding, encoding[i]); nodes[i] = create_huff_node(i, -2, node_encoding); } huff_node *root = build_encoded_tree(nodes); return root; }
huff_node *build_encoded_tree(huff_node *nodes[]) { huff_node *root = NULL; // All the encodings in the tree have to be dynamically allocated char* root_encoding = xmalloc(1); root_encoding[0] = '\0'; root = create_huff_node(-1, -2, root_encoding); for(int i = 0;i < 256; i++){ insert_encoded_node(root, nodes[i]); } return root; }