chuffman-tree

Why is the tree constructed this way incorrect?


The result of decoding the tree constructed using the first write-up is correct, but the tree constructed using the second write-up is decoded incorrectly, why? I thought they were equivalent but they are not, and I can't figure out the problem within the second version :( To make things clear, here is the correct diagram of the tree I want to construct: Graph of the tree

Tree* buildTree() {
    Tree* root, * curr;
    root = getNode('0');//set irrelevant node value to be '0'
    curr = root->left = getNode('0');
    curr->left = getNode('b');
    curr->right = getNode('g');
    curr = root->right = getNode('0');
    curr->right = getNode('e');
    curr = curr->left = getNode('0');
    curr->right = getNode('0');
    curr->right->left = getNode('a');
    curr->right->right = getNode('h');
    curr = curr->left = getNode('0');
    curr->right = getNode('d');
    curr = curr->left = getNode('0');
    curr->left = getNode('c');
    curr->right = getNode('f');
    return root;

}

And here the second version(the wrong one)

Tree* buildTree() {
    Tree* root, * curr;
    root = getNode('0');//不是解码关键节点的点,值都设为‘0’,*100
    root->left =root->right = getNode('0');
    root->left->left = getNode('b');//19
    root->left->right = getNode('g');//21
    root->right->right = getNode('e');
    curr = root->right->left = getNode('0');
    curr->left = curr->right = getNode('0');
    curr->right->left = getNode('a');
    curr->right->right = getNode('h');
    curr = curr->left = getNode('0');
    curr->left = getNode('0');
    curr->right = getNode('d');
    curr->left->left = getNode('c');
    curr->left->right = getNode('f');
    return root;

}

I tried comparing the two write-ups one-to-one with the tree illustration and didn't find any difference, but it turns out that they construct different results for decoding the tree.


Solution

  • The problem is that when you construct the tree you reuse node when you shouldn't be. For example here:

    root->left = root->right = getNode('0');
    

    This is wrong because now left and right are the same node. And now when you set stuff on the node:

    root->left->left = getNode('b');
    

    Since root->left and root->right are the same, you also affected root->right

    You might be confused by what the original code is doing here:

    curr = root->left = getNode('0');
    

    This means that curr points to the same node as root->left. Modifying curr also modify root->left.

    To fix this problem, make sure you create a new node every time, e.g.

    root->left = getNode('0');
    root->right = getNode('0');