If neither tempLeft nor tempRight is a leaf, you've got an infinite loop:
while((tempLeft->letter != letter) || (tempRight->letter != letter))
{
if((tempRight->is_leaf()) &&
(tempRight->letter == letter))
{
// no
}
else if ((tempLeft->is_leaf()) &&
(tempLeft->letter == letter))
{
// no
}
else if ((tempRight->is_leaf()) &&
(tempRight->letter != letter))
{
// no
}
else if ((tempLeft->is_leaf()) &&
(tempLeft->letter != letter))
{
// no
}
}
There must be something you intend to do in the case where the nodes are not leaves. Maybe recurse?
(Per comments) You might be working with a variant of Huffman trees in which you can guarantee that every node is either a leaf or has one leaf child. If you can guarantee that, then the above does not matter (it would be good to throw an exception if it occurs). However, real-world Huffman trees do not have this property.
When one child is a leaf and the other is not your target letter, you attempt to set a new tempNode
, tempLeft
and tempRight
for the next go around the loop.
else if ((tempRight->is_leaf()) &&
(tempRight->letter != letter))
{
tempNode = root->left;
tempLeft = tempNode->left;
tempRight = tempNode->right;
encode_str = encode_str + '0';
}
However, since you never modify root
, tempNode = root->left
will always set tempNode
to the same node.
You probably want tempNode = tempNode->left
.
To avoid repetition of code, you can move
tempLeft = tempNode->left;
tempRight = tempNode->right;
... to be the first thing that happens in the while()
loop.
You say that debugging hasn't helped. Have you actually run it in a debugger?
Write a unit test that sets up your tree; validates that the tree actually contains what you intend it to; and calls this function with one letter. Decide how you think execution should proceed. Now run the code in a debugger, stepping through it. When it stops doing what you think it should, you'll be able to reason about why.
A common way to implement Huffman Encoding is to have an array of leaf nodes, so you can reach the node through simple array access:
NodePtr nodeA = nodes[0];
... and have a pointer to the parent in each node, and a field indicating whether it's the left or right child, so that you can easily traverse the tree backwards, from leaf to root, building up a code (in reverse):
string code = "";
NodePtr node = nodeA;
while(node->parent != NULL) {
code = node->code + code;
node = node->parent;
}