哈夫曼编码编译器实践报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机软件基础
课程设计
报告
设计题目:哈夫曼编\译码器
专业信息工程(系统工程方向)
班级09系统1班
学生董健
学号***********
指导教师陈金辉
一、设计题目
设计题目一哈夫曼编\译码器
设计要求:
1.初始化,键盘输入字符集大小n,n个字符和n个权植,建立哈夫曼树。
2.编码,利用建好的huffman树生成huffman编码;
3.输出编码;
4.译码功能;
5.字符和频度如下:
字符空格A B C D E F G H I J K L M N O P Q
频度186 64 13 22 32 103 21 15 47 57 1 2 32 20 57 63 15 1
字符R S T U V W X Y Z
频度48 51 80 23 8 18 1 16
1.1 问题分析
构造哈夫曼树时,首先将由n各字符形成的n个叶子节点存放到数组HTNode 的前n个分量中,然后根据前面介绍的哈夫曼方法的基本思想,不断将两个小子树合并为一个较大的子树,每次构成的新子树,每次构成的新子树的根节点顺序放到HTNode数组中的前n个分量的后面。译码功能,假定电文中只使用A、B、C、D、E、F6种字符,若进行等长编码,它们分别需要3位二进制字符,可一次编码为000、001、010、011、100、101。
1.2 数据结构与算法设计
哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。
在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。
最简单的二进制编码方式是等长编码。若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。哈夫曼树课用于构造使电文的编码总长最短的编码方案。
哈夫曼树编\译码器流程图
1.3 核心代码
哈夫曼编\译码器程序的主要代码如下所示:
#include
#include
#include
#include
#define N 50 //义用N表示50叶节点数
#define M 2*N-1 //用M表示节点总数当叶节点数位n时总节点数为2n-1 #define MAXSIZE 100
typedef struct
{
char data; //结点值
int weight; //权值
int parent; //双亲结点
int lchild; //左孩子结点
int rchild; //右孩子结点
}HTNode;
typedef struct
{
char cd[N]; //存放哈夫曼码
int start; //从start开始读cd中的哈夫曼码
}HCode;
void CreateHT(HTNode ht[],int n) //调用输入的数组ht[],和节点数n {
int i,k,lnode,rnode;
int min1,min2;
for (i=0;i<2*n-1;i++)
ht[i].parent=ht[i].lchild=ht[i].rchild=-1; //所有结点的相关域置初值-1 for (i=n;i<2*n-1;i++) //构造哈夫曼树
{
min1=min2=32767; //int的范围是-32768—32767
lnode=rnode=-1; //lnode和rnode记录最小权值的两个结点位置
for (k=0;k<=i-1;k++)
{
if (ht[k].parent==-1) //只在尚未构造二叉树的结点中查找
{
if (ht[k].weight { min2=min1;rnode=lnode; min1=ht[k].weight;lnode=k; } else if (ht[k].weight { min2=ht[k].weight;rnode=k; } } } ht[lnode].parent=i;ht[rnode].parent=i; //两个最小节点的父节点是i ht[i].weight=ht[lnode].weight+ht[rnode].weight; //两个最小节点的父节点权值为两个最小节点权值之和 ht[i].lchild=lnode;ht[i].rchild=rnode; //父节点的左节点和右节点} } void CreateHCode(HTNode ht[],HCode hcd[],int n) { int i,f,c; HCode hc; for (i=0;i { hc.start=n;c=i; f=ht[i].parent; while (f!=-1) //循序直到树根结点结束循环 { if (ht[f].lchild==c) //处理左孩子结点 hc.cd[hc.start--]='0'; else //处理右孩子结点 hc.cd[hc.start--]='1'; c=f;f=ht[f].parent; } hc.start++; //start指向哈夫曼编码hc.cd[]中最开始字符 hcd[i]=hc; } } void DispHCode(HTNode ht[],HCode hcd[],int n) //输出哈夫曼编码的列表 { int i,k; printf(" 输出哈夫曼编码:\n");