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;
}
Beispiel #3
0
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;
}