




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、电子科技大学信息与软件工程学院实验报告电 子 科 技 大 学实 验 报 告 课程名称: 数据结构与算法 学生姓名: 陈*浩 学 号: * 点名序号: * 指导教师: 钱* 实验地点: 基础实验大楼 实验时间: 2015.5.7 2014-2015-2学期 信息与软件工程学院实 验 报 告(二)学生姓名:陈*浩 学 号:* 指导教师:钱*实验地点: 科研教学楼A508 实验时间:2015.5.7一、实验室名称:软件实验室 二、实验项目名称:数据结构与算法树三、实验学时:4四、实验原理:霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法。1952
2、年,David A. Huffman在麻省理工攻读博士时所发明的。在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。二者相比,e使用了一
3、般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。霍夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1*L1+W2*L2+W3*L3+.+Wn*Ln),N个权值Wi(i=1,2,.n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,.n)。可以证明霍夫曼树的WPL是最小的。五、实验目的:本实验通过
4、编程实现赫夫曼编码算法,使学生掌握赫夫曼树的构造方法,理解树这种数据结构的应用价值,并能熟练运用C语言的指针实现构建赫夫曼二叉树,培养理论联系实际和自主学习的能力,加强对数据结构的原理理解,提高编程水平。六、实验内容:(1)实现输入的英文字符串输入,并设计算法分别统计不同字符在该字符串中出现的次数,字符要区分大小写;(2)实现赫夫曼树的构建算法;(3)遍历赫夫曼生成每个字符的二进制编码;(4)显示输出每个字母的编码。七、实验器材(设备、元器件):PC机一台,装有C或C+语言集成开发环境。八、数据结构与程序:/* * *程序名称:哈夫曼树的相关操作 * * *程序内容:生成哈夫曼树及其编码表、对
5、字符串进行编码等 * * *编写作者:陈家浩 * * *完成时间:2015.5.15 * */#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXSIZE 10000char file_address100; /全局通用文件地址typedef struct hnode / 哈夫曼树的节点结构定义 int weight; int lchild, rchild, parent;THNode, * TpHTree;typedef struct huffman_code / 哈夫曼编码
6、表的元素结构定义 int weight; / 编码对应的权值 char * pcode; / 指向编码字符串的指针THCode, *TpHcodeTab;/*/ * *声明函数/*TpHcodeTab build_codesheet( TpHTree pht, int leaves_num); / 根据哈夫曼树得到编码表TpHTree create_huffman_tree(int weights, int n ); / 构造哈夫曼树void select_mintree(TpHTree , int , int *, int *); / 从森林中选择权值最小的两棵子树void destroy_
7、codesheet(TpHcodeTab codesheet, int n); / 销毁哈夫曼编码表int read_file(char file_address100, char *message); / 从文本文件读入字符串 int calc_freq(char text, int *freq, char *dict, int n); / 统计字符串text中字符出现的频率/*/ * *主函数/*int main(void)int i, msg_num,choose;char s; /清空缓存int leaves_num = 0;doTpHTree pht = NULL; /建立树根TpH
8、codeTab codesheet; /建立编码表char msgMAXSIZE; /建立信息数组int *weights = NULL; /建立频率数组char *dict = NULL; /建立字符数组printf(" - n""-哈夫曼树-n"" - ");printf("n读取文件还是手动输入信息?n"" 1:手动输入信息n"" 2:读取文件n"" 请选择:");scanf("%d",&choose);if(choose
9、 = 1)printf("请输入信息:n");scanf("%c",&s); /清理键盘缓存gets(msg);msg_num = strlen(msg);elseprintf("输入文件地址(例如:F:filename.txt):n");scanf("%c",&s); /清理键盘缓存gets(file_address); /输入文件地址msg_num = read_file( file_address, msg); /读取文本文件leaves_num = calc_freq( msg, &
10、weights, &dict, msg_num );/统计文本串中的字符频率,同时得到哈夫曼树的叶节点数pht = create_huffman_tree( weights, leaves_num ); /创建哈夫曼树codesheet = build_codesheet( pht, leaves_num ); /构造哈夫曼编码表printf("n-字符频率编码表-n");printf("符号 - 频率 - 编码n");for(i = 0; i < leaves_num ; i+)printf("%4c - %-3d - %-6s
11、n", dicti, codesheeti.weight, codesheeti.pcode);printf("-n");destroy_codesheet( codesheet, leaves_num); /销毁哈夫曼编码表if(pht)/释放所有临时空间free(pht);if(dict)free(dict);if(weights)free(weights);printf("nt0:结束nt1:继续n""t请选择:");scanf("%d",&choose);while(choose);ret
12、urn 0;/*/ * *构造哈夫曼编码表/*TpHcodeTab build_codesheet( TpHTree pht, int leaves_num )int i, cid, pid, cursor, len;TpHcodeTab sheet;char * pch = (char *) malloc( leaves_num + 1 );if( !pch )printf("申请空间失败!");exit(0);memset( pch, 0, (leaves_num + 1) ); / 清零新分配的空间sheet = ( TpHcodeTab )malloc( sizeo
13、f( THCode ) * leaves_num );if( !sheet )printf("申请编码表内存空间失败!");exit(0);for( i = 0; i < leaves_num; +i )sheeti.weight = phti.weight;for( i = 0; i < leaves_num; +i )cursor = leaves_num;cid = i;pid = phtcid.parent;while( pid!= -1 ) /不为根节点 if (phtpid.lchild = cid)pch-cursor = '0'
14、/ 左分支编码为'0'elsepch-cursor = '1' / 右分支编码为'1'cid = pid;pid = phtcid.parent;len = leaves_num - cursor + 1;sheeti.pcode = ( char * )malloc( len );if( !sheeti.pcode )printf("为节点%d的编码申请内存空间失败!", i);exit(0);memset( sheeti.pcode, 0, len );strncpy( sheeti.pcode, &pchcurs
15、or, strlen(&pchcursor) );free(pch);return sheet;/*/ * *构造哈夫曼树/*TpHTree create_huffman_tree( int weights, int n )TpHTree pht;int minA, minB; / 用于保存权值最小的两棵子树的序号int i, a = 0;if( n < 1 )printf("没有叶子节点!n");return 0; a = (2 * n) - 1;pht = ( TpHTree ) malloc( sizeof( THNode ) * a );if( !ph
16、t )printf("分配数组空间失败!n");exit(0);for( i = 0; i < a; +i ) / 哈夫曼数组初始化 phti.weight = (i < n) ? weightsi : 0;phti.lchild = -1;phti.rchild = -1;phti.parent = -1;for( i = n; i < a; +i )select_mintree( pht, (i-1), &minA, &minB );phtminA.parent = i;phtminB.parent = i; phti.lchild =
17、 minA;phti.rchild = minB;phti.weight = phtminA.weight + phtminB.weight;return pht;/*/ * *选出权值最小的两棵子树/*void select_mintree(TpHTree pht, int n, int *minA, int *minB)int id, min1 = -1, min2 = -1; /最小值,次小值int maxa = 10000, maxb = 10000;for(id = 0; id <= n; id+) if(phtid.parent = -1)if( phtid.weight &
18、lt; maxa )min2 = min1;min1 = id;maxa = phtid.weight;else if(phtid.weight < maxb )min2 = id;maxb = phtid.weight; *minA = min1;*minB = min2;return;/*/ * *销毁哈夫曼编码表/*void destroy_codesheet(TpHcodeTab sheet, int n) int i; for(i = 0; i < n; +i) free(sheeti.pcode); free(sheet); return;/*/ * *读取文本文件 /
19、*int read_file(char file_address100, char *message)int str_len; /字符串长度FILE * pFile = NULL;pFile = fopen( file_address, "r");/打开文件 if(!pFile)printf("打开文件失败!n");exit(0);elseprintf("打开文件成功!n");memset(message, 0, MAXSIZE);/清除缓冲 if( fgets( message, MAXSIZE, pFile ) = NULL)pr
20、intf( "fgets errorn" );exit(0);elseprintf( "成功读取文件,内容如下:n%sn", message);str_len = strlen(message);fclose(pFile);return str_len;/*/ * *统计字符出现的频率/*int calc_freq(char text, int *freq, char *dict, int n)/n为字符串长度int i, k;int char_num = 0;int * chars; /不同种类的字符char * fre; /字符的出现频率int times256 = 0;for(i = 0; i < n; +i) /各个字符出现的频率 timestexti+;for(i = 0; i < 256; i+)/不同字符的个数 if( timesi > 0 )char_num+;chars = (int*)malloc(sizeof(int)*char_num);if( !chars )printf
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公路ppp合同范本
- 分红比例合同范本
- 公路规划合同范本
- 协议合同范本写法
- 兼职还款合同范本
- pos机推广合同范本
- 入股店铺协议合同范本
- 义齿加工合同范本模板
- 京东入职合同范本
- 医院整体转让合同范本
- 安全生产责任制考核制度和考核表(完整版)
- 19J102-1 19G613混凝土小型空心砌块墙体建筑与结构构造
- 建筑垃圾清运及处置 投标方案(技术方案)
- 2024年常州信息职业技术学院单招职业技能测试题库及答案解析
- 《中国陶瓷史》课件-1-中国陶瓷史概述
- 英语教师课堂提问省公开课一等奖全国示范课微课金奖课件
- 经皮式气管切开术
- 2024嘉兴市城南街道招聘笔试参考题库附带答案详解
- 个人维修收款收据
- 代办电瓶车车牌照委托书
- 智慧农业中的智能农机与农具技术
评论
0/150
提交评论