C - 如何遍历霍夫曼树并生成相应的霍夫曼代码?

时间:2015-12-01 01:25:32

标签: c binary-tree huffman-code tree-traversal

我目前正致力于从标准输入中读取文本的程序,从数据中创建一个霍夫曼树,然后为霍夫曼树中的符号生成霍夫曼代码。

我能够创建霍夫曼树,其由包含符号的树节点结构,符号的频率,符号的霍夫曼代码以及指向节点和右节点的指针组成。但是,我有点坚持如何遍历树并修改每个节点"代码"根据它在树上的位置。

基本上我要问的是如何在根据树中的位置修改节点的元素时遍历二叉树。

最初我尝试了以下几点:

void generateCodes (struct HuffTreeNode* root, unsigned long bitShift)
{
  struct HuffTreeNode* current = root;
  if (root != NULL)
  {
    current->code |= 0<<bitShift;
    generateCodes(root->left,bitShift+1);
    current->code |= 1<<bitShift;
    generateCodes(root->right,bitShift+1);

  }
}

然而,这并没有奏效,而且我对接下来的尝试感到茫然。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你已经形成了树。所以现在仍然是遍历。

    17
    /\
   /  7
  /   /\
 10  /  3
 /\ C4  /\
A6 B4   D1 E2

现在初步你只是把它们(0或1)放在array.Left子链接--1右子链接-0

因此,在您放置a[currrent]=1的数组中,然后调用huffmancode(tree->left,current+1)

如果转到右侧子树a[current]=0,则调用huffmancode(tree->right,current+1)

到达叶节点打印数组。

伪代码:( printtree)

    if (root->left exists)
    {
        a[current] = 0;
        printtree(root->left, a, current + 1);
    }

    if (root->right exists)
    {
        a[current] = 1;
        printtree(root->right, a,current + 1);
    }


    if (root is leaf)
    {
        print a[].
    }

答案 1 :(得分:1)

我认为你的树是正确的(并且是最佳的)构建的。

每个霍夫曼代码是从根到定义符号的叶子的路径。在遍历左弧时添加0,在遍历右弧时添加1

因此,获取所有对symbol,code的列表的方法包括以递归方式遍历树。您保持从根到当前访问节点的当前路径,当您到达叶子时,生成对符号(将存储在叶子中)和当前路径。

用于管理当前路径的数据结构是堆栈。

因此,算法可以如下:

void codes(struct Node * root, struct Stack * s)
{
  if (is_leaf(root))
    {
      char symbol = // symbol stored in the node
      char * code = // the reversed stack content; that is the code of current leaf
      printf("symbol %c has code %s\n", symbol, code);
    }

  s->push('0');
  codes(LLINK(root), s);
  s->pop();

  s->push('1');
  codes(RLINK(root), s);
  s->pop();
}

我向您介绍堆栈和其他元组件(is_leaf()LLINK(root),...)的实现细节。

您可以改进算法以生成位

我希望会有所帮助

相关问题