文档详情

实验四哈夫曼编码.doc

发布:2017-01-03约3.36千字共6页下载文档
文本预览下载声明
实验四 贪心算法 实验目的和要求 (1)了解前缀编码的概念,理解数据压缩的基本方法; (2)掌握最优子结构性质的证明方法; (3)掌握贪心法的设计思想并能熟练运用 (4)证明哈夫曼树满足最优子结构性质; (5)设计贪心算法求解哈夫曼编码方案; (6)设计测试数据,写出程序文档。 实验内容 设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为 {w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。 实验环境 Dev c++ 实验学时 2学时,必做实验 数据结构与算法 /*示例 ****哈夫曼编码**** 请输入结点个数:8 输入这8个元素的权值(均为整形): 1:27 2:4 3:87 4:21 5:2 6:21 7:1 8:25 */ #include stdio.h #include stdlib.h #include string.h typedef struct { unsigned int weight; //用来存储各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组,存储哈夫曼树 ///选择两个parent为0,且weight最小的结点s1和s2 void Select(HuffmanTree *ht,int n,int *s1,int *s2) { int i,min; for(i=1; i=n; i++) { if((*ht)[i].parent==0) { min=i; break; } } for(i=1; i=n; i++) { if((*ht)[i].parent==0) { if((*ht)[i].weight(*ht)[min].weight) min=i; } } *s1=min; for(i=1; i=n; i++) { if((*ht)[i].parent==0 i!=(*s1)) { min=i; break; } } for(i=1; i=n; i++) { if((*ht)[i].parent==0 i!=(*s1)) { if((*ht)[i].weight(*ht)[min].weight) min=i; } } *s2=min; } ///构造哈夫曼树ht,w存放已知n个权值 void CrtHuffmanTree(HuffmanTree *ht,int *w,int n) { int m,i,s1,s2; m=2*n-1; //总共的结点数 *ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(i=1; i=n; i++) //1-n号存放叶子结点,初始化 { (*ht)[i].weight=w[i]; (*ht)[i].LChild=0; (*ht)[i].parent=0; (*ht)[i].RChild=0; } for(i=n+1; i=m; i++) //非叶子结点的初始化 { (*ht)[i].weight=0; (*ht)[i].LChild=0; (*ht)[i].parent=0; (*ht)[i].RChild=0; } printf(\n?哈夫曼树为: \n); for(i=n+1; i=m; i++) //创建非叶子结点,建哈夫曼树 { /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2*/ Select(ht,i-1,s1,s2); (*ht)[s1].parent=i; (*ht)[s2].parent=i; (*ht)[i].LChild=s1; (*ht)[i].RChild=s2; (*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight; printf(%d (%d, %d)\n,(*ht)[i].weight,(*ht)[s1].weight,(*ht)[s2].weight); } printf(\n); } //从叶子结点到根,逆向求每个叶子结
显示全部
相似文档