标签:ant 分享 init 子节点 个数 VID malloc std sha
Huffmam coding是David A. Huffman在MIT上学期间发明的一种编码方式,并以他的名字命名。Huffman coding 和 Shannon-Fano coding方法正好相反,Huffman coding是从下到上,Shannon-Fano coding 是从上到下。
3 剩下的一个节点是根节点,编码结束。
Symbol | A | B | C | D | E |
---|---|---|---|---|---|
count | 15 | 7 | 6 | 6 | 5 |
probabilities | 0.38461538 | 0.17948718 | 0.15384615 | 0.15384615 | 0.12830513 |
首先,D&E权重最小,将它们相加构成新的节点,权重0.28205128, 两个子节点分配0和1,如上图b所示.
Symbol | A | D&E | B | C |
---|---|---|---|---|
count | 15 | 11 | 7 | 6 |
probabilities | 0.38461538 | 0.28205128 | 0.17948718 | 0.15384615 |
然后,合并最小的两个符号B&C,组成新节点B&C,权重0.33333333,两个子节点分配0和1,如上图c所示
Symbol | A | B&C | D&E |
---|---|---|---|
count | 15 | 13 | 11 |
probabilities | 0.38461538 | 0.33333333 | 0.28205128 |
再将B&C和D&E合并,组成新节点B&C&D&E,如上图d所示;最后,将A和B&C&D&E合并组成root节点。最后得到编码如下表所示
Symbol | A | B | C | D | E |
---|---|---|---|---|---|
code | 0 | 100 | 101 | 110 | 111 |
计算得到平均字长:\[\frac{1\ bits*15+3\ bits*(7+6+6+5)}{39 symbols} \approx 2.23\ bits\ per \ symbol\]
#include <stdio.h>
#include <malloc.h>
char word[10] = {‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘, ‘I‘, ‘J‘};
int weight[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
typedef struct HuffmanNode{
int word;
int weight;
int parrent, lchild, rchild;
}HN;
HN *HT=NULL;
int Select(HN *H, int n, int *s1, int *s2)
{
/*寻找权值最小节点*/
/*先找到第一个没有父母节点的节点*/
int i=0;
for(; i<n; i++){
if(H[i].parrent==0) {
*s1 = i;
break;
}
}
/*寻找权值最小节点*/
for(; i<n; i++){
if(H[i].parrent == 0 && H[i].weight < H[*s1].weight){
*s1=i;
}
}
/*寻找权值次小节点*/
int j=0;
for(; j<n; j++){
if(H[j].parrent==0 && *s1!=j) {
*s2 = j;
break;
}
}
for(; j<n; j++){
if(H[j].parrent == 0 && *s1!=j && H[j].weight < H[*s2].weight){
*s2=j;
}
}
}
int creatHuffmanTree(int n)
{
/*分配并初始化节点*/
int m=2*n-1;
HT = (HN*)malloc(sizeof(HN)*m);
for(int i=0; i<m; i++) {
HT[i].parrent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for(int i=0; i<n; i++){
HT[i].weight=weight[i];
HT[i].word=word[i];
}
//printf("init is OK.\n");
/*构造Huffman树*/
for(int i=n; i<m; i++){
int s1, s2;
/*寻找前i个数据中的最小值*/
Select(HT, i, &s1, &s2);
HT[i].weight=HT[s1].weight+HT[s2].weight;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[s1].parrent=i;
HT[s2].parrent=i;
//printf("%d and %d have some parents %d!\n", s1, s2, i);
}
}
int main() {
printf("Huffman coding test!\n");
creatHuffmanTree(10);
for(int i=0; i<10; i++){
int j=i;
/*编码从叶子节点遍历到根节点,逆序输出编码*/
while(HT[j].parrent != 0){
if(HT[HT[j].parrent].lchild == j)
printf("0");
else if(HT[HT[j].parrent].rchild == j)
printf("1");
else {
printf("ERROR! Parents‘ child is not me.");
free(HT);
return 1;
}
j=HT[j].parrent;
}
/*输出编码对应字符*/
printf(" word is %c\n", HT[i].word);
}
free(HT);
return 0;
}
标签:ant 分享 init 子节点 个数 VID malloc std sha
原文地址:https://www.cnblogs.com/lab601/p/10096270.html