簡體   English   中英

編碼霍夫曼二進制樹

[英]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
        }
     }

在節點不是葉子的情況下,必須要做某些事情。 也許是遞歸?

(每條評論)您可能正在使用霍夫曼樹的變體,您可以保證每個節點都是葉子或有一個葉子。 如果你可以保證,那么上面的內容並不重要(如果發生異常會拋出異常)。 然而,現實世界的霍夫曼樹沒有這個屬性。


當一個孩子是一個葉子而另一個孩子不是你的目標字母時,你會嘗試為下一個環路設置一個新的tempNodetempLefttempRight

    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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM