收藏 分销(赏)

实验七哈夫曼编码.doc

上传人:pc****0 文档编号:7477111 上传时间:2025-01-06 格式:DOC 页数:6 大小:70.50KB 下载积分:10 金币
下载 相关 举报
实验七哈夫曼编码.doc_第1页
第1页 / 共6页
实验七哈夫曼编码.doc_第2页
第2页 / 共6页


点击查看更多>>
资源描述
算法设计与分析实验报告 姓名:杨勇涛 班级:计科102班 一、实验名称: 哈夫曼编码 时间:2012年4月4日,星期三,第四节 地点:12#311 二、实验目的及要求 设计任务: 从键盘输入一串电文字符能输出对应的哈夫曼编码。同时,能翻译由哈夫曼编码生成的代码串,输出相应的电文字符串。 设计要求: (1)从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树及哈夫曼编码。 (2)利用已经建好的哈夫曼树,对输入的字符串进行编码,输出编码序列。 (3)利用已建好的哈夫曼树对输入的二进制编码进行译码,并输出结果。 设计任务: 从键盘输入一串电文字符能输出对应的哈夫曼编码。同时,能翻译由哈夫曼编码生成的代码串,输出相应的电文字符串。 设计要求: (1)从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树及哈夫曼编码。 (2)利用已经建好的哈夫曼树,对输入的字符串进行编码,输出编码序列。 (3)利用已建好的哈夫曼树对输入的二进制编码进行译码,并输出结果。 三、实验环境 Vc++ 四、实验内容 从键盘输入一串电文字符能输出对应的哈夫曼编码。同时,能翻译由哈夫曼编码生成的代码串,输出相应的电文字符串。 五、算法描述及实验步骤 一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。) 二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。 三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。 四、重复二和三两步,直到集合F中只有一棵二叉树为止。 六、调试过程及实验结果 七、总结 通过这次编程使我对哈弗曼编码有了更深刻的理解,并且学会了将之前学过的东西运用到程序中来。 八、源程序 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码 typedef struct { unsigned int weight; //用来存放各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 //选择两个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("\nHuffmanTree: \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"); } //哈夫曼树建立完毕 //从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码 void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n) { char *cd; int i,start,p; unsigned int c; hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); //分配n个编码的头指针 cd=(char *)malloc(n*sizeof(char)); //分配求当前编码的工作空间 cd[n-1]='\0'; //从右向左逐位存放编码,首先存放编码结束符 for(i=1; i<=n; i++) //求n个叶子结点对应的哈夫曼编码 { start=n-1; //初始化编码起始指针 for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) //从叶子到根结点求编码 if( (*ht)[p].LChild==c) cd[--start]='0'; //左分支标0 else cd[--start]='1'; //右分支标1 hc[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个编码分配空间 strcpy(hc[i],&cd[start]); } free(cd); for(i=1; i<=n; i++) printf("HuffmanCode of %3d is %s\n",(*ht)[i].weight,hc[i]); printf("\n"); } void main() { HuffmanTree HT; HuffmanCode HC; int *w,i,n,wei,m; printf("\nn = " ); scanf("%d",&n); w=(int *)malloc((n+1)*sizeof(int)); printf("\ninput the %d element's weight:\n",n); for(i=1; i<=n; i++) { printf("%d: ",i); fflush(stdin); scanf("%d",&wei); w[i]=wei; } CrtHuffmanTree(&HT,w,n); CrtHuffmanCode(&HT,&HC,n); }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服