[英]Encoding a Huffman Binary tree
我正在嘗試編寫一個接受霍夫曼樹和角色的函數。 然后它應該編碼字符並返回它。
到目前為止的代碼:
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;
}
到目前為止,這還沒有奏效,調試也沒有幫助我。 任何人都可以幫助我,或至少告訴我,我的想法是否正確。
如果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
。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.