哈夫曼树的创建 实验报告
Posted fengzeng666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了哈夫曼树的创建 实验报告相关的知识,希望对你有一定的参考价值。
代码参考严蔚敏《数据结构》
1 #include<string.h> 2 #include<stdlib.h> 3 #include<stdio.h> 4 5 int m,s1,s2; 6 7 typedef struct 8 { 9 unsigned int weight; 10 unsigned int parent,lchild,rchild; 11 } HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树 12 typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表 13 14 void Select(HuffmanTree HT,int n) 15 { 16 int i,j; 17 for(i = 1; i <= n; i++) 18 if(!HT[i].parent) 19 { 20 s1 = i; 21 break; 22 } 23 for(j = i+1; j <= n; j++) 24 if(!HT[j].parent) 25 { 26 s2 = j; 27 break; 28 } 29 for(i = 1; i <= n; i++) 30 if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i)) 31 s1=i; 32 for(j = 1; j <= n; j++) 33 if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j)) 34 s2=j; 35 } 36 37 void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[], int *w, int n) 38 { 39 // 算法6.13 40 // w存放n个字符的权值(均>0),构造哈夫曼树HT, 41 // 并求出n个字符的哈夫曼编码HC 42 int i, j; 43 char *cd; 44 int p; 45 int cdlen; 46 47 if (n<=1) 48 return; 49 m = 2 * n - 1; 50 HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元未用 51 for (i=1; i<=n; i++) //初始化 52 { 53 HT[i].weight=w[i-1]; 54 HT[i].parent=0; 55 HT[i].lchild=0; 56 HT[i].rchild=0; 57 } 58 for (i=n+1; i<=m; i++) //初始化 59 { 60 HT[i].weight=0; 61 HT[i].parent=0; 62 HT[i].lchild=0; 63 HT[i].rchild=0; 64 } 65 puts(" 哈夫曼树的构造过程如下所示:"); 66 printf("HT初态: 结点 weight parent lchild rchild"); 67 for (i=1; i<=m; i++) 68 printf(" %4d%8d%8d%8d%8d",i,HT[i].weight, 69 HT[i].parent,HT[i].lchild, HT[i].rchild); 70 for (i=n+1; i<=m; i++) // 建哈夫曼树 71 { 72 // 在HT[1..i-1]中选择parent为0且weight最小的两个结点, 73 // 其序号分别为s1和s2。 74 Select(HT, i-1); 75 HT[s1].parent = i; 76 HT[s2].parent = i; 77 HT[i].lchild = s1; 78 HT[i].rchild = s2; 79 HT[i].weight = HT[s1].weight + HT[s2].weight; 80 printf(" select: s1=%d s2=%d ", s1, s2); 81 printf(" 结点 weight parent lchild rchild"); 82 for (j=1; j<=i; j++) 83 printf(" %4d%8d%8d%8d%8d",j,HT[j].weight, 84 HT[j].parent,HT[j].lchild, HT[j].rchild); 85 86 } 87 88 //------无栈非递归遍历哈夫曼树,求哈夫曼编码 89 cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间 90 p = m; 91 cdlen = 0; 92 for (i=1; i<=m; ++i) // 遍历哈夫曼树时用作结点状态标志 93 HT[i].weight = 0; 94 while (p) 95 { 96 if (HT[p].weight==0) // 向左 97 { 98 HT[p].weight = 1; 99 if (HT[p].lchild != 0) 100 { 101 p = HT[p].lchild; 102 cd[cdlen++] =‘0‘; 103 } 104 else if (HT[p].rchild == 0) // 登记叶子结点的字符的编码 105 { 106 HC[p] = (char *)malloc((cdlen+1) * sizeof(char)); 107 cd[cdlen] =‘