我正在尝试编写一个接受霍夫曼树和角色的函数。然后它应该对角色进行编码并将其返回。
到目前为止的代码:
string encode(NodePtr root, char letter)
{
string encode_str; //a string which will store the encoded string
NodePtr tempNode = root; //Initialize a new Huffman to be used in this function
NodePtr tempLeft = root->left;
NodePtr tempRight = root->right;
//A while loop that goes on until we find the letter we want
while((tempLeft->letter != letter) || (tempRight->letter != letter))
{
if((tempRight->is_leaf()) && (tempRight->letter == letter)) //check if is leaf and is letter
{
encode_str = encode_str + '1';
}
else if ((tempLeft->is_leaf()) && (tempLeft->letter == letter)) //check if is leaf and is letter
{
encode_str = encode_str + '0';
}
else if ((tempRight->is_leaf()) && (tempRight->letter != letter)) //check if is leaf and is NOT letter
{
tempNode = root->left;
tempLeft = tempNode->left;
tempRight = tempNode->right;
encode_str = encode_str + '0';
}
else if ((tempLeft->is_leaf()) && (tempLeft->letter != letter)) //check if is leaf and is NOT letter
{
tempNode = root->right;
tempLeft = tempNode->left;
tempRight = tempNode->right;
encode_str = encode_str + '1';
}
}
return encode_str;
}
到目前为止,这还没有奏效,调试对我也没有帮助。任何人都可以帮助我,或者至少告诉我我的想法是否正确。
答案 0 :(得分:2)
如果tempLeft和tempRight都不是叶子,那么你就会有一个无限循环:
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
}
}
在节点不是叶子的情况下,必须要做某些事情。也许递归?
(每条评论)您可能正在使用霍夫曼树的变体,您可以在其中保证每个节点都是叶子或有一个叶子。如果你可以保证,那么上面的内容并不重要(如果发生异常会抛出异常)。然而,现实世界的霍夫曼树没有这种属性。
当一个孩子是一片叶子而另一个孩子不是你的目标字母时,你会尝试设置一个新的tempNode
,tempLeft
和tempRight
,以便下一次循环。< / p>
else if ((tempRight->is_leaf()) &&
(tempRight->letter != letter))
{
tempNode = root->left;
tempLeft = tempNode->left;
tempRight = tempNode->right;
encode_str = encode_str + '0';
}
但是,由于您从不修改root
,tempNode = root->left
始终会将tempNode
设置为同一节点。
您可能想要tempNode = tempNode->left
。
为避免重复代码,您可以移动
tempLeft = tempNode->left;
tempRight = tempNode->right;
...成为while()
循环中发生的第一件事。
你说调试没有帮助。你真的在调试器中运行它吗?
编写一个设置树的单元测试;验证树实际上包含您想要的内容;并用一个字母调用此函数。决定你认为执行应该如何进行。现在在调试器中运行代码,逐步执行它。当它停止做你认为应该做的事情时,你就能够解释原因。
实现Huffman编码的一种常用方法是拥有一个叶子节点数组,这样您就可以通过简单的数组访问来访问节点:
NodePtr nodeA = nodes[0];
...并且在每个节点中都有一个指向父节点的指针,以及一个指示它是左子节点还是右子节点的字段,这样您就可以轻松地从树到底遍历树,构建代码(在反向):
string code = "";
NodePtr node = nodeA;
while(node->parent != NULL) {
code = node->code + code;
node = node->parent;
}