OK,昨天我们对huffman数的基本知识,以及huffman树的创建做了一些简介,http://www.cnblogs.com/Frank-C/p/5017430.html
今天接着聊:
huffman树创建完成之后,我们如何去得到huffman编码呢?
图12.4_1 huffman树形结构
图12.4_2 huffman存储结构(数组)
首先,以上面的树为例,我们必须明白几个要点:
1:从什么地方开始访问这颗树:根节点 , index 2n-1 = 15
2:访问的规则:向左为0 向右为1
3:以什么样的访问循序去访问呢?
好说,
(1): 询问是否有左孩子,一直向左走,直到左孩子为零,如果此时右孩子也为零,证明已经找到了一个叶子结点(信息元)。(当然,在访问的同时进行编码记录)
(2): 原路返回一层(编码同时减一),询问是否有右孩子,有,进入右孩子,无,再返回上一层
一直重复(1)和(2)步,直到最终回退到更节点,在回到根节点的parent,即此时迭代器(index)为零
当然,我只是说了一下大概的步骤,具体的代码实现,还得是细之又细,往下看!!!!!! 有木有
*HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); /* 分配n个字符编码的头指针向量([0]不用) */ cd=(char*)malloc(n*sizeof(char)); /* 分配求编码的工作空间 即传递(temp)空间*/ c=m; //直接指向最上面那个非叶子节点 cdlen=0; for(i=1;i<=m;++i)/* 遍历赫夫曼树时用作结点状态标志 直接把全部节点置为零 此时这棵树已经建立了 故权重已经没有多大用处了*/ (*HT)[i].weight=0; while(c) { if((*HT)[c].weight==0) //负责向左 { /* 向左 */ (*HT)[c].weight=1; /* ************* */ if((*HT)[c].lchild!=0) /*如果权为零的左孩子节点不是第一个元素(下标为0)*/ { c=(*HT)[c].lchild; cd[cdlen++]='0'; } /*看这个左孩子有没有右孩子 如果右孩子为零(即没有右孩子),那么是一个叶子节点*/ else if((*HT)[c].rchild==0) { /* 登记叶子结点的字符的编码 */ (*HC)[c]=(char *)malloc((cdlen+1)*sizeof(char)); cd[cdlen]='