XXX 学院本科
数据结构课程设计总结报告
设计题目:实验一、哈夫曼编/译码器
学生姓名:XXX
系
专
班
学
别:XXX
业:XXX
级:XXX
号:XXX
指导教师:XXX XXX
2012 年 6 月 21 日
xxx 学院
课 程 设 计 任 务 书
一、赫夫曼编译码器
题目
专业、班级 xxx
学号 xxx 姓名 xxx
主要内容、基本要求、主要参考资料等:
1. 主要内容
利用哈夫曼编码进行信息通信可大大提高信道利用率,缩短信息传输时间,降低
传输成本。要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传
来的数据进行译码(复原)。对于双工信道(既可以双向传输信息的信道),每端
都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼的编/译码
系统。
2. 基本要求
系统应具有以下功能:
(1)C:编码(Coding)。对文件 tobetrans 中的正文进行编码,然后将结果存
入文件 codefile 中,将以此建好的哈夫曼树存入文件 HuffmanTree 中
(2)D:解码(Decoding)。利用已建好的哈夫曼树将文件 codefile 中的代码进
行译码,结果存入 textfile 中。
(3)P:打印代码文件(Print)。将文件 codefile 以紧凑格式显示在终端上,
每行 50 个代码。同时将此字符形式的编码文件写入文件 codeprint 中。
(4)T:打印哈夫曼树(Tree Printing)。将已在内存中的哈夫曼树以直观的方
式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件
treeprint 中。
3. 参考资料:数据结构(C 语言版) 严蔚敏、吴伟民编著;
数据结构标准教程 胡超、闫宝玉编著
完 成 期 限: 2012 年 6 月 21 日
指 导 教 师 签 名 :
课程负责人签名:
2012 年 6 月
21 日
2
一、设计题目(任选其一)
实验一、哈夫曼编/译码器
二、 实验目的
1 巩固和加深对数据结构的理解,提高综合运用本课程所学知识的能力;
2 深化对算法课程中基本概念、理论和方法的理解;
3 巩固构造赫夫曼树的算法;
4 设计试验用程序实验赫夫曼树的构造。
三、运行环境(软、硬件环境)
Windows xp sp3,Visual C++ 6.0 英文版
四、算法设计的思想
(1)初始化赫夫曼树,输入文件 tobetrans.txt 中各字符及其权值,并保存于
hfmtree.txt 文件中
(2)编码(Coding)。对文件 tobetrans 中的正文进行编码,然后将结果存入文件
codefile 中
(3)D:解码(Decoding)。利用已建好的哈夫曼树将文件 codefile 中的代码进
行译码,结果存入 textfile 中。
(4)P:打印代码文件(Print)。将文件 codefile 以紧凑格式显示在终端上,每
行 50 个代码。同时将此字符形式的编码文件写入文件 codeprint 中。
(5)T:打印哈夫曼树(Tree Printing)。将已在内存中的哈夫曼树以直观的方式
显示在终端上,同时将此字符形式的哈夫曼树写入文件 treeprint 中。
五、 流程图
3
六、 算法设计分析
1.赫夫曼树节点的数据类型定义为:
typedef struct{
//赫夫曼树的结构体
char ch;
int weight;
//权值
int parent,lchild,rchild;
} HTNode,*HuffmanTree;
2. void HuffmanCoding(HuffmanTree &,char *,int *,int);建立赫夫曼树的
算法,此函数块调用了 Select()函数。void select(HuffmanTree HT,int j,int
*x,int *y);从已建好的赫夫曼树中选择 parent 为 0,weight 最小的两个结点。
3.利用已建好的哈夫曼树从文件 hfmtree.txt 中读入,对文件中的正文进行编
码,然后将结果存入文件 codefile.txt 中。
4. coding
编码功能:对输入字符进行编码
5. Decoding
译码功能: 利用已建好的哈夫曼树将文件 codefile.txt 中的代码进行译码,结
果存入文件 textfile.txt 中。
6. Print() 打印功能函数:输出哈夫曼树以及对应的编码。
4
七、源代码
//////////////////////////////////////////////////////////////////
////////////////////////
#include
#include
#include
//定义赫夫曼树结点的结构体
typedef struct{
char ch;
int weight;
//增加一个域,存放该节点的字符
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
//指向赫夫曼编码的指针
void tips();
//打印操作选择界面
void HuffmanCoding(HuffmanTree &,char *,int *,int);
//建立赫夫
曼树的算法
void select(HuffmanTree HT,int j,int *x,int *y);
//从已建好的
赫夫曼树中选择 parent 为 0,weight 最小的两个结点
void Init();
void Coding();
//编码
void Decoding();
//译码
void Print_code();
//打印译码好的代码
void Print_tree();
//打印哈夫曼树
int Read_tree(HuffmanTree &); //从文件中读入赫夫曼树
void find(HuffmanTree &HT,char *code,char *text,int i,int m);
//
译码时根据 01 字符串寻找相应叶子节点的递归算法
5
void Convert_tree(unsigned char T[100][100],int s,int *i,int j);
//
将内存中的赫夫曼树转换成凹凸表形式的赫夫曼树
HuffmanTree HT;
//全局变量
int n=0;
//全局变量,存放赫夫曼树叶子结点的数目
int main()
{
char select;
while(1)
{
tips();
scanf("%c",&select);
switch(select)
//选择操作,根据不同的序号选择不同的操作
{
case '1':Init();
break;
case '2':Coding();
break;
case '3':Decoding();
break;
case '4':Print_code();
break;
6
case '5':Print_tree();
break;
case '0':exit(1);
default :printf("Input error!\n");
}
getchar();
}
return 0;
}
void tips()
//操作选择界面
{
printf(" -----------------------------------------------------\n");
printf(" --
请选择操作
--\n");
printf(" -----------------------------------------------------\n");
printf("
\n");
printf(" ---------------------1 初始化赫夫曼树 ---------------\n");
printf(" ---------------------2 编码
---------------\n");
printf(" ---------------------3 译码
---------------\n");
printf(" ---------------------4 打印代码文件
---------------\n");
printf(" ---------------------5 打印赫夫曼树
---------------\n");
printf(" ---------------------0 退出
---------------\n");
printf(" -----------------------------------------------------\n");
}
7
//初始化函数,输入 n 个字符及其对应的权值,根据权值建立哈夫曼树,并
将其存于文件 hfmtree 中
void Init()
{
FILE *fp;
int i,n,w[52];
//数组存放字符的权值
char character[52];
//存放 n 个字符
printf("\n 输入字符个数 n:");
scanf("%d",&n);
//输入字符集大小
printf("输入%d 个字符及其对应的权值:\n",n);
for (i=0;i