简体   繁体   中英

strange bug with huffman decoding tree

I made a question about the algorithm and implementation earlier, but ran into a problem that I am unable to solve.

I was able to take the prefixes from a text file and get them into a vector, for example:

a 0
b 100
c 101
d 11

.

[0, a, 1, 0, 0, b, 1, 0, 1, c, 1, 1, d]

So my code:

  • starts with a root node
  • iterate through the vector. if we get a 0, take the current node and have it's left pointer point to a new node. if we get a 1, take the current node and have it's right pointer point to a new node. if it's a letter, store that character into the current node and start over from the root.

(a node just holds a value and has left and right pointers)

void Foo:: build(vector<char> v) {
    node* root = new node; 

    vector<char>:: iterator itr;

    node* current = root; 
    cout << " *" << endl;

    for(itr =  v.begin(); itr != v.end(); itr++) {
        cout << "(" << *itr << ")" << endl;

        if (!isdigit(*itr)) {
            current->value = *itr; 
            current = root; 
            cout << "*" << endl;
        }
        if (*itr == '0') {
            cout << "<-" << endl; 
            current->left = new node; 
            current = current->left; 
        }
        if (*itr == '1') {
            cout << "->" << endl; 
            current->right = new node; 
            current = current->right; 
        }
    }

    nodeVector.push_back(*root); 
}

. If you're curious about the couts, * means at the root. so for 'a', it would start from the root * , encounter 0 and go <- left to put the 'a' in that node, then start over from the root *. I just did this to see if it was going left and right like it was supposed to and that seems to be okay.

 *
(0)
<-
(a)
*
(1)
->
(0)
<-
(0)
<-
(b)
*
(1)
->
(0)
<-
(1)
->
(c)
*
(1)
->
(1)
->
(d)
*

The problem I'm having is strange. The only letters that seem to work are 'a' and 'd'. For example, root->left->value would give me 'a', root->right->right->value would give 'd', but root->right->left->right->value which should be 'c' doesn't seem like it was ever put in the node location. my program then crashes when I try to get this value. When I try to decode a string of bits, the message is incorrect because it is only able to do 'd' and 'a'. This had led me to suspect it was the building of the tree. Any suggestions would be highly appreciated!

Before allocating a new node you need to check if that path has already been allocated before. For example

if (*itr == '0') {
    cout << "<-" << endl;
    if (current->left) current = current->left;
                  else current = (current->left = new node);
}

6502 is correct.

Each time your itteration loop passes you are constructing a new path down the tree. The one on the left is fine because it is never overwritten (but it would also fail if you had a node and 2 leaves rather than being a leaf on it's own). The path on the right is re-allocated each time and overwrites the previous node that was created, thus only your last entry of "d" is visible. In otherwords "b" and "c" were created but the pointer to them was lost (overwritten) each time a new right entry was created.

As 6502 pointed out, you need to check if the node is created already. But your code probably fails because the empty pointers were not initialized to 0, thus the code proceeded as if the node existed, but it didn't. for every new node you must initialize the empty pointers left and right if you intend to test them for content. For example:

if (*itr == '0') {
    cout << "<-" << endl;
    if (current->left) current = current->left;
    else
    {
        current = (current->left = new node);
        current->left = 0;  // initialize your empty pointers!
        current=>right = 0; // initialize your empty pointers!
    }
}

Note, a much better place to put the pointer initialization is in the new constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM