赫夫曼编码实验报告

赫夫曼编码实验报告
赫夫曼编码实验报告

赫夫曼编码

班级:2008211130班姓名:韦泰丞学号:08210822 班内序号:16

一、实验目的

构建所输入符号(及权值)的哈夫曼树,并利用该树求出各符号的编码,深入理解最优二叉树的概念及其特性。

二、[问题描述]

三、读入各个符号及其权值,求各符号的哈夫曼编码。

四、[基本要求]

五、读入各个符号及其权值,建立哈夫曼树;利用建立的哈夫曼树对各符号进行编码,输出编码结果。

六、[选做内容]

七、将所建立的哈夫曼树以直观的方式(树或凹入形式的表)显示。

八、具体实现过程。

第一步,任务分析

赫夫曼编码译码的实现,首先要的是根据给定的n个权值构造赫夫曼树。通过遍历次二叉树完成赫夫曼编码。

第二部,程序构思。

构造赫夫曼树:

(1)将给定的n个权值{w1,w2,…,wn}作为n个根结点的权值构造一个具有n棵二叉树的森林{T1,T2,…,Tn},其中每棵树只有一个根结点;

(2)在森林中选取两棵根结点权值最小的二叉树作为左右子树,构造一棵新二叉树,新二叉树新结点的权值为这两棵树根的权值之和;

(3)在森林中,将上面选择的这两棵权值最小的二叉树从森林中删除,并将刚刚新构造的二叉树加入到森林中;

(4)重复上面的(2)和(3),知道森林中只有一棵二叉树为止。这棵二叉树就是赫夫曼树。

编码过程:

1.抽象数据类型定义

typedef struct HTNode{

int weight;

int parent;

int lchild;

int rchild;

}HTNode1;//动态分配数组存储赫夫曼树

2.根据构造思想,选取最小权值

void Select(struct HTNode *HT, int n, int *s1, int *s2)

{

int i;

int min1,index1;

int min2,index2;

//给第一个最小值min1赋初值

for(i = 1; i <= n; i++) {

if (HT[i].parent == 0)

{

min1 = HT[i].weight;

index1 = i;

break;

}

}

//找出第一个最小的权值

for( ; i <= n; i++)

{

if ((HT[i].parent == 0) && (HT[i].weight < min1))

{

min1 = HT[i].weight;

index1 = i;

}

}

//给第二个最小值min2赋初值

for(i =1 ; i <= n; i++)

{

if ((HT[i].parent == 0) && (i != index1) && (HT[i].weight >= min1)) {

min2 = HT[i].weight;

index2 = i;

break;

}

}

//找出第二个最小的权值

for( ; i <= n; i++)

{

if ((HT[i].parent == 0) && (i != index1) && (HT[i].weight < min2)) {

min2 = HT[i].weight;

index2 = i;

}

}

*s1 = index1;

*s2 = index2;

}

3.下面是核心函数的编写,求解赫夫曼编码,一棵有n个叶子结点的赫夫曼树共有2n-1个结点,可以存储在一个大小为2n-1的一维数组中。n个字符的编码可存储在二维数组中,因为每个字符的编码长度不等,所以需要动态分配数组存储赫夫曼编码。

将构成电文的每个不同字符作为叶子结点,其权值为电文中字符的使用频率或次数,构造赫夫曼树。我们约定左分支表示字符’0’,右分支表示字符’1’,则可以从根结点到叶子结点的路径上分支字符组成的字符串作为该叶子结点字符的编码。

//求解赫夫曼编码

int HuffmanCoding(struct HTNode *HT, char **HC, int *w, int n)

{

int m; //赫夫曼树总的结点数

struct HTNode *p;

int i;

int s1,s2;

char *cd;

int c,f;

int start;

if (n <= 1)

return ERROR;

m = 2 * n - 1;

for(p = HT + 1, i = 1;i <= n;i++,p++)

{

p->weight = w[i-1];

p->lchild = 0;

p->rchild = 0;

p->parent = 0;

}

for(; i <= m; i++, p++)

{

p->weight = 0;

p->lchild = 0;

p->rchild = 0;

p->parent = 0;

}

// 创建赫夫曼树

for(i = n + 1; i <= m; i++)

{

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;

}

// 从叶子到根逆向求每个字符的赫夫曼树

cd = (char *)malloc( n * sizeof(char));//分配求编码的工作空间

cd[n-1] = 0;//编码结束符

for(i = 1; i <= n; i++) //逐个字符求赫夫曼编码

{

start = n-1;//编码结束符位置

for( c = i, f = HT[i].parent; f != 0;c = f, f = HT[f].parent)//从叶子到根逆向求编码if (HT[f].lchild == c)

cd[--start]='0';

else

cd[--start]='1';

HC[i] = (char *)malloc((n - start) * sizeof(char));//为第i个字符编码分配空间

strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC

}

free(cd);//释放工作空间

return OK;

}

4.最后就是编写主函数。

void main()

{

int i,m,n;

int *w = NULL;

struct HTNode *HT;

char **HC;

char *C = NULL;

printf("请输入字符的个数n: \n");

scanf("%d",&n);

w = (int *)malloc((n + 1) * sizeof(int *));

C = (char *)malloc((n+2)*sizeof(char *));

for(i = 0;i

{

printf("输入字符C[%d]=",i+1);

scanf("%s",&C[i]);

printf("输入权值w[%d]=",i+1);

scanf("%d",&w[i]);

}

m = 2 * n - 1;

HT = (struct HTNode *)malloc((m + 1) * sizeof(struct HTNode));//0号单元未用

HC = (char **)malloc(( n + 1) * sizeof(char *));//分配n个字符编码的头指针向量

HuffmanCoding(HT, HC, w, n);

printf("\n\n树的链表存储形式为:\n");

printf("----------------------------------\n");

printf(" N weight parent lchild rchild\n");

for ( i = 1; i <=m; i++)

printf(" %2d %2d %2d %2d %2d\n",

i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

printf("----------------------------------\n");

printf("\n\n赫夫曼编码是:\n");

printf("Sign Symbol Code\t\tLength \n");

for ( i = 1; i <=n; i++)

printf("%c %2d %s\t\t%2d\n",C[i-1], HT[i].weight, HC[i], strlen(HC[i]));

}

九、实验总结:

我们可以二叉树来设计二进制的前缀编码来实现赫夫曼编码。赫夫曼编码是能够使电文总长度最短的编码方式。

十、实验中遇到的问题及分析:

在编写程序的过程中,遇到一些字符错误,缺少符号是在所难免的,可以通过认真检查看出。然后就是核心函数,求解赫夫曼编码的编写,在对刚学习的树的内容进行基本复习以及对赫夫曼树的基本了解后,参考课本,开始编写,并慢慢调试。在没有语法错误时运行程序,出现结果与实际预期不符,运用单步调试,检查出空间分配上存在的问题以及算法问题,慢慢改正。最后,代入具体数据开始验证。确定准确无误即可。

十一、实验总结。

通过此次实验,我对二叉树有了更深的理解,也能更熟练的应用与实践当中。同时也对自己的C语言进行了巩固。

.

哈夫曼树编码译码实验报告(DOC)

数据结构课程设计设计题目:哈夫曼树编码译码

目录 第一章需求分析 (1) 第二章设计要求 (1) 第三章概要设计 (2) (1)其主要流程图如图1-1所示。 (3) (2)设计包含的几个方面 (4) 第四章详细设计 (4) (1)①哈夫曼树的存储结构描述为: (4) (2)哈弗曼编码 (5) (3)哈弗曼译码 (7) (4)主函数 (8) (5)显示部分源程序: (8) 第五章调试结果 (10) 第六章心得体会 (12) 第七章参考文献 (12) 附录: (12)

在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 第二章设计要求 对输入的一串电文字符实现哈夫曼编码,再对哈夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。设计实现的功能: (1) 哈夫曼树的建立; (2) 哈夫曼编码的生成; (3) 编码文件的译码。

哈夫曼树 实验报告

计算机科学与技术学院数据结构实验报告 班级2014级计算机1班学号20144138021 姓名张建华成绩 实验项目简单哈夫曼编/译码的设计与实现实验日期2016.1.5 一、实验目的 本实验的目的是进一步理解哈夫曼树的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。 二、实验问题描述 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,此实验即设计这样的一个简单编/码系统。系统应该具有如下的几个功能: 1、接收原始数据。 从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree.dat中。 2、编码。 利用已建好的哈夫曼树(如不在内存,则从文件hfmtree.dat中读入),对文件中的正文进行编码,然后将结果存入文件codefile.dat中。 3、译码。 利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat中。 4、打印编码规则。 即字符与编码的一一对应关系。 5、打印哈夫曼树, 将已在内存中的哈夫曼树以直观的方式显示在终端上。 三、实验步骤 1、实验问题分析 1、构造哈夫曼树时使用静态链表作为哈夫曼树的存储。 在构造哈夫曼树时,设计一个结构体数组HuffNode保存哈夫曼树中各结点的信息,根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有2n-1个结点,所以数组HuffNode的大小设置为2n-1,描述结点的数据类型为: Typedef strcut { Int weight;/*结点权值*/ Int parent; Int lchild; Int rchild; }HNodeType; 2、求哈夫曼编码时使用一维结构数组HuffCode作为哈夫曼编码信息的存储。 求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,没回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值,由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路径上各分支所组成的0、1序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码位所求编码的高位码,所以设计如下数据类型:

数据结构实验报告哈夫曼树

数据结构实验报告实验题目: Huffman编码与解码 姓名: 学号: 院系:

实验名称: Huffman编码与解码实验 问题描述: 本实验需要以菜单形式完成以下功能: 1、输入电文串 2、统计电文串中各个字符及其出现的次数 3、构造哈弗曼树 4、进行哈弗曼编码 5、将电文翻译成比特流并打印出来 6、将比特流还原成电文 数据结构的描述: 逻辑结构: 本实验可用二叉树实现,其逻辑结构为一对二的形式,即一个结点对应两个结点。在实验过程中我们也应用到了栈的概念。 存储结构: 使用结构体来对数据进行存储: typedef struct { int weight; int parent,lc,rc; }HTNode,*HuffmanTree; typedef struct LNode { char *elem; int stacksize; int top; }SqStack; 在main函数里面定义一个哈弗曼树并实现上述各种功能。 程序结构的描述: 本次实验一共构造了10个函数: 1.void HuffTree(HuffmanTree &HT,int n[],int mun); 此函数根据给定的mun个权值构建哈弗曼树,n[]用于存放num个权值。 2、void Select(HuffmanTree &HT,int n,int i,int &s1,int &s2);

此函数用于在HT[1,i-1]中选择parent为0且weight为最小的两个结点,其下标分别为s1,s2、 3.void HuffmanCoding(HuffmanTree HT,char **&HC,int n); 此函数从哈弗曼树HT上求得n 个叶子结点的哈弗曼编码并存入数组HC中。 4.void Coding(HuffmanTree HT,char **HC,int root,SqStack &S); 此函数用于哈弗曼编码,先序遍历哈弗曼树HT,求得每个叶子结点的编码字符串,存入数组HC,S为一个顺序栈,用来记录遍历路径,root就是哈弗曼数组HT中根结点的位置下标。 5.void InitStack(SqStack &S); 此函数用于初始化一个栈。 6.void Pop(SqStack &S,char e); 此函数为出栈操作。 7.void Push(SqStack &S,char e); 此函数为进栈操作。 8.int StackLength(SqStack S); 此函数用于求栈长,返回一个int型的值。 9.int Find(char a,char s[],int num); 此函数用于查找字符a在电文串中的位置。 10.int Recover(HuffmanTree HT,char **HC,char string[],char a[],char b[],int n); 此函数用于将比特流还原成电文。 调试分析: 输入任意一个字符串,如输入welcometoustc:运行结果如下:

霍夫曼树实验报告

实验二二叉树的遍历及霍夫曼编码 班级:计科1101班 学号:0909101605 姓名:杜茂鹏 2013年5月22日

一、实验目的 掌握二叉树的建立及遍历操作,霍夫曼编码基本操作及存储结构表示 二、实验内容 1. 系统要求包含以下功能 1)初始化:从终端读入字符集大小n,以及n个字符和n个权值(或者读入字符集和频度数据文件),建立哈夫曼树,并将哈夫曼树存入到文件HfmTree 中。 2)编码:利用已建好的哈夫曼树(如果不在内存中,则从文件中读入),从文件ToBeTran中读入原文,对原文进行编码,将编码后的结果存入文件CodeFile 中。 3)译码:利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。 4)打印:打印输出哈夫曼树,显示ToBeTran, TextFile和CodeFile文件的内容。 三、实验要求 1.在上机前写出全部源程序; 2.能在机器上正确运行程序; 3.用户界面友好。 四、概要设计 1)首先动态分配数组存储霍夫曼树及存储霍夫曼编码表,然后从终端或文件读入霍夫曼树的字符变量及其频度,初始化建立霍夫曼树并将其写入文件HfmTree.txt中。 2)从指定的文件succe.txt中读入原文,利用已经编好的霍夫曼树对其编码,将编码结果写入文件Coding.txt保存。 3)利用已建好的哈夫曼树将文件Coding.txt中的代码进行译码,结果存入文件decoding.txt中。

五、测试数据: 2.原文内容“THIS IS MY PROGRAM” 六、详细设计 实验内容(原理、操作步骤、程序代码) //建立霍夫曼树,对原文进行编码、译码 #include #include #include #include typedef struct tree { char ch; int weight;//权值 int parent,lchild,rchild; }HTNode,*HuffmanTree;//动态分配数组存储霍夫曼树typedef char **HuffmanCode;//动态分配数组存储霍夫曼编码表void Select(HuffmanTree &HT,int* s1,int* s2,int n) { int j; int min1=10000; for(j=1;j<=n;j++) { if(HT[j].parent==0&&min1>HT[j].weight)

哈弗曼数据结构专题实验报告

数据结构与程序设计专题 实验报告 :学号:班级:信息45班 :学号:班级:信息45班 :学号:班级:信息45班 实验指导老师:峰 实验地点:西一楼一层计算机中心机房 实验结束日期:12月5日 联系:

一.实验任务: 对于给定的源文档 SourceDoc.txt, 1) 统计其中所有字符的频度(某字符的频度等于其出现的总次数除以总字符数),字符包括字母(区分大小写)、标点符号及格式控制符(空格、回车等)。 2) 按频度统计结果构建哈夫曼编码表。 3) 基于哈夫曼编码表进行编码,生成对应的二进制码流,并输出到文件 Encode.dat,完成信源的编码过程。 4) 根据生成的哈夫曼编码表,对二进制码流文件 Encode.dat 进行解码,把结果输出到文件 TargetDoc.txt,完成信源的解码过程。 5) 判断 TargetDoc.txt 与 SourceDoc.txt 容是否一致,以验证编解码系统的正确性。 二.实验容: 1) 线性链表的构建以及排序; 2) 哈夫曼树的构建; 3) 基于哈夫曼码进行编码; 4) 对二进制码进行解码; 5)对生成文件与原文件进行比较; 三.程序的算法描述

四.程序运行结果:

五.源程序代码: #include #include #include #include typedef struct aa {char data; double rate; int count; struct aa *next; struct aa *pre; char haffmancode[120]; }NODE; NODE *creat(char b[])

哈夫曼树的实验报告1

一、需求分析 1、本演示程序实现Haffman编/译码器的作用,目的是为信息收发站提供一个编/译系统, 从而使信息收发站利用Haffman编码进行通讯,力求达到提高信道利用率,缩短时间,降低成本等目标。系统要实现的两个基本功能就是:①对需要传送的数据预先编码; ②对从接收端接收的数据进行译码; 2、本演示程序需要在终端上读入n个字符(字符型)及其权值(整形),用于建立Huffman 树,存储在文件hfmanTree.txt中;如果用户觉得不够清晰还可以打印以凹入表形式显示的Huffman树; 3、本演示程序根据建好的Huffman树,对文件的文本进行编码,结果存入文件CodeFile 中;然后利用建好的Huffman树将文件CodeFile中的代码进行译码,结果存入文件TextFile中;最后在屏幕上显示代码(每行50个),同时显示对CodeFile中代码翻译后的结果; 4、本演示程序将综合使用C++和C语言; 5、测试数据: (1)教材例6-2中数据:8个字符,概率分别是0.05,0.29,0.07,0.08,0.14,0.23,0.03, 0.11,可将其的权值看为5,29,7,8,14,23,3,11 (2)用下表给出的字符集和频度的实际统计数据建立Haffman树,并实现以下报文的编码和 一、概要设计 1、设定哈夫曼树的抽象数据类型定义 ADT Huffmantree{ 数据对象:D={a i| a i∈Charset,i=1,2,3,……n,n≥0} 数据关系:R1={< a i-1, a i >| a i-1, a i∈D, i=2,3,……n} 基本操作: Initialization(&HT,&HC,w,n,ch) 操作结果:根据n个字符及其它们的权值w[i],建立Huffman树HT,用字符数组ch[i]作为中间存储变量,最后字符编码存到HC中; Encodeing(n) 操作结果:根据建好的Huffman树,对文件进行编码,编码结果存入到文件CodeFile 中 Decodeing(HT,n) 操作结果:根据已经编译好的包含n个字符的Huffman树HT,将文件的代码进行翻译,结果存入文件TextFile中 } ADT Huffmantree

赫夫曼树实验报告

实验报告 实验原理: 霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法。1952年,David A. Huffman在麻省理工攻读博士时所发明的。 在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。 例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。二者相比,e使用了一般编码的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是最小的。 实验目的: 本实验通过编程实现赫夫曼编码算法,使学生掌握赫夫曼树的构造方法,理解树这种数据结构的应用价值,并能熟练运用C语言的指针实现构建赫夫曼二叉树,培养理论联系实际和自主学习的能力,加强对数据结构的原理理解,提高编程水平。 实验内容: (1)实现输入的英文字符串输入,并设计算法分别统计不同字符在该字符串中出现的次数,字符要区分大小写;

哈夫曼编码解码实验报告

哈夫曼编码解码实验 1.实验要求 掌握二叉树的相关概念 掌握构造哈夫曼树,进行哈夫曼编码。 对编码内容通过哈夫曼树进行解码。 2.实验内容 通过二叉树构造哈夫曼树,并用哈夫曼树对读取的txt文件进行哈夫曼编码。编码完成后通过哈夫曼树进行解码。 #include #include #define MAX 100 //定义哈夫曼树的存储结构 typedef struct { char data; int weight; int parent; int lch; int rch; }HuffNode; //定义哈夫曼编码的存储结构 typedef struct { char bit[MAX]; int start; }HuffCode; HuffNode ht[2*MAX]; HuffCode hcd[MAX]; int Coun[127]={0}; int n; char s1[200000]; char text[5000]; //构造哈夫曼树 void HuffmanTree() {

int i,j,k,left,right,min1,min2; //printf("输入叶子的节点数:"); //scanf("%d",&n); printf("字符数量=%d\n",n); for(i=1;i<=2*n-1;i++) { ht[i].parent=ht[i].lch=ht[i].rch=0; } j=0; for(i=1;i<=n;i++) { /*getchar(); printf("输入第%d个叶子节点的值:",i); scanf("%c",&ht[i].data); printf("输入该节点的权值:"); scanf("%d",&ht[i].weight); */ for(;j<127;j++) { if(Coun[j]!=0) { ht[i].data=j; //printf("%c",ht[i].data); ht[i].weight=Coun[j]; //printf("%d",ht[i].weight); break; } } j++; } printf("\n"); for(i=1;i<=n;i++) { printf("%c",ht[i].data); } printf("\n"); for(i=n+1;i<=2*n-1;i++) {//在前n个结点中选取权值最小的两个结点构成一颗二叉树 min1=min2=10000;//为min1和min2设置一个比所有权值都大的值 left=right=0; for(k=1;k<=i-1;k++) { if(ht[k].parent==0)//若是根结点 //令min1和min2为最小的两个权值,left和right

哈夫曼树实验报告

哈夫曼树实验报告 Company number:【0089WT-8898YT-W8CCB-BUUT-202108】

计算机科学与技术学院数据结构实验报告 班级 2014级计算机1班学号姓名张建华成绩 实验项目简单哈夫曼编/译码的设计与实现实验日期一、实验目的 本实验的目的是进一步理解哈夫曼树的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。 二、实验问题描述 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,此实验即设计这样的一个简单编/码系统。系统应该具有如下的几个功能: 1、接收原始数据。 从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件中。 2、编码。 利用已建好的哈夫曼树(如不在内存,则从文件中读入),对文件中的正文进行编码,然后将结果存入文件中。 3、译码。 利用已建好的哈夫曼树将文件中的代码进行译码,结果存入文件中。 4、打印编码规则。 即字符与编码的一一对应关系。 5、打印哈夫曼树, 将已在内存中的哈夫曼树以直观的方式显示在终端上。 三、实验步骤 1、实验问题分析 1、构造哈夫曼树时使用静态链表作为哈夫曼树的存储。 在构造哈夫曼树时,设计一个结构体数组HuffNode保存哈夫曼树中各结点的信息,根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有2n-1个结点,所以数组HuffNode的大小设置为2n-1,描述结点的数据类型为: Typedef strcut { Int weight;/*结点权值*/ Int parent; Int lchild; Int rchild; }HNodeType; 2、求哈夫曼编码时使用一维结构数组HuffCode作为哈夫曼编码信息的存储。 求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,没回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值,由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路

哈夫曼树实验报告

数据结构实验报告 实验名称:实验三哈夫曼树 学生姓名: 班级: 班内序号: 学号: 日期: 程序分析: 存储结构:二叉树 程序流程: template class BiTree { public: ) 1.初始化链表的头结点

2.获得输入字符串的第一个字符,并将其插入到链表尾部,n=1(n记录的是链 表中字符的个数) 3.从字符串第2个字符开始,逐个取出字符串中的字符 将当前取出的字符与链表中已经存在的字符逐个比较,如果当前取出的 字符与链表中已经存在的某个字符相同,则链表中该字符的权值加1。 如果当前取出的字符与链表中已经存在的字符都不相同,则将其加入到 链表尾部,同时n++ =n(tSize记录链表中字符总数,即哈夫曼树中叶子节点总数) 5.创建哈夫曼树 6.销毁链表 源代码: void HuffmanTree::Init(string Input) { Node *front=new Node; 建哈夫曼树(void HuffmanTree::CreateCodeTable(Node *p)) 算法伪代码: 1.创建一个长度为2*tSize-1的三叉链表 2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前tSize个结点 的data域,并将对应结点的孩子域和双亲域赋为空 3.从三叉链表的第tSize个结点开始,i=tSize 3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其 下标x,y。 3.2将下标为x和y的哈夫曼树的结点的双亲设置为第i个结点 3.3将下标为x的结点设置为i结点的左孩子,将下标为y的结点设置为 i结点的右孩子,i结点的权值为x结点的权值加上y结点的权值,i 结点的双亲设置为空 4. 根据哈夫曼树创建编码表

哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)

目录 摘要………………………………………………………………………..………………II Abstract …………………………………………………………………………..………... II 第一章课题描述 (1) 1.1 问题描述 (1) 1.2 需求分析…………………………………………………..…………………………… 1 1.3 程序设计目标…………………………………………………………………………… 第二章设计简介及设计方案论述 (2) 2.1 设计简介 (2) 2.2 设计方案论述 (2) 2.3 概要设计 (2) 第三章详细设计 (4) 3.1 哈夫曼树 (4) 3.2哈夫曼算 法 (4) 3.2.1基本思 想 (4) 3.2.2存储结 构 (4)

3.3 哈夫曼编码 (5) 3.4 文件I/O 流 (6) 3.4.1 文件流 (6) 3.4.2 文件的打开与关闭 (7) 3.4.3 文件的读写 (7) 3..5 C语言文件处理方式…………………………………………………………………… 第四章设计结果及分析 (8) 4.1 设计系统功能 (8) 4.2 进行系统测试 (8) 总结 (13) 致谢 (14) 参考文献 (15) 附录主要程序代码 (16) 摘要 在这个信息高速发展的时代,每时每刻都在进行着大量信息的传递,到处都离不开信息,它贯穿在人们日常的生活生产之中,对人们的影响日趋扩大,而利用哈夫曼编码

进行通信则可以大大提高信道利用率,缩短信息传输时间,降低传输成本。在生产中则可以更大可能的降低成本从而获得更大的利润,这也是信息时代发展的趋势所在。本课程设计的目的是使学生学会分析待加工处理数据的特性,以便选择适当的逻辑结构、存储结构以及进行相应的算法设计。学生在学习数据结构和算法设计的同时,培养学生的抽象思维能力、逻辑推理能力和创造性的思维方法,增强分析问题和解决问题的能力。此次设计的哈夫曼编码译码系统,实现对给定报文的编码和译码,并且任意输入报文可以实现频数的统计,建立哈夫曼树以及编码译码的功能。这是一个拥有完备功能的系统程序,对将所学到的知识运用到实践中,具有很好的学习和研究价值. 关键词:信息;通讯;编码;译码;程序 Abstract This is a date that information speeding highly development and transmit

哈夫曼树及其操作-数据结构实验报告(2)

电子科技大学 实验报告 课程名称:数据结构与算法 学生姓名:陈*浩 学号:************* 点名序号: *** 指导教师:钱** 实验地点:基础实验大楼 实验时间: 2014-2015-2学期 信息与软件工程学院

实验报告(二) 学生姓名:陈**浩学号:*************指导教师:钱** 实验地点:科研教学楼A508实验时间:一、实验室名称:软件实验室 二、实验项目名称:数据结构与算法—树 三、实验学时:4 四、实验原理: 霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法。1952年,David A. Huffman在麻省理工攻读博士时所发明的。 在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。 例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。二者相比,e使用了一般编码的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是最小的。

哈夫曼树及编码综合实验报告

《用哈夫曼编码实现文件压缩》 实验报告 课程名称数据结构B 实验学期 2017 至 2018 学年第一学期学生所在院部计算机学院 年级 2016 专业班级信管B162 学生姓名学号 成绩评定: 1、工作量: A(),B(),C(),D(),F( ) 2、难易度:A(),B(),C(),D(),F( ) 3、答辩情况: 基本操作:A(),B(),C(),D(),F( ) 代码理解:A(),B(),C(),D(),F( ) 4、报告规范度:A(),B(),C(),D(),F( ) 5、学习态度:A(),B(),C(),D(),F( )总评成绩:_________________________________ 指导教师: 兰芸

用哈夫曼编码实现文件压缩 1、了解文件的概念。 2、掌握线性链表的插入、删除等算法。 3、掌握Huffman树的概念及构造方法。 4、掌握二叉树的存储结构及遍历算法。 5、利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。 微型计算机、Windows 7操作系统、Visual C++6.0软件 输入的字符创建Huffman树,并输出各字符对应的哈夫曼编码。 五.系统设计 输入字符的个数和各个字符以及权值,将每个字符的出现频率作为叶子结点构建Huffman树,规定哈夫曼树的左分支为0,右分支为1,则从根结点到每个叶子结点所经过的分支对应的0和1组成的序列便为该结点对应字符的哈夫曼编码。 流程图如下 1.输入哈夫曼字数及相应权值

相应代码 int main() { HuffmanTree HTree; HuffmanCode HCode; int *w, i; int n,wei; //编码个数及权值 printf("请输入需要哈夫曼编码的字符个数:"); scanf("%d",&n); w=(int*)malloc((n+1)*sizeof(int)); for(i=1; i<=n;i++) { printf("请输入第%d字符的权值:",i); fflush(stdin); scanf("%d",&wei); w[i]=wei; } HuffmanCoding(&HTree,&HCode,w,n); return 1; } 2.输出HT初态(每个字符的权值)

哈夫曼树实验报告(付原C语言程序)

哈夫曼树实验报告 需求分析: 从终端读入一串字符,利用建立好的哈夫曼树对其进行编码,储存到文件当中去,然后从文件读入哈夫曼编码,针对每个字母对其进行译码,翻译为原来的信息。 二、概要设计 程序分为以下几个模块: 1、从终端读入字符集大小,n个字符和n个权值,建立哈夫曼树,写入文件hfmTree中去。 2、对hfmTree进行编码,建立hfm编码表。 3、从文件ToTran读入信息,根据hfm编码表对其进行hfm编码,将编码后的信息写入文件Codefile 中去 4、对Codefile文件反向译码,结果储存在Textfile中去。 5、将建立的hfmTree打印在终端上,并储存于相应的Treeprint文件中去。 抽象的数据定义如下: 哈夫曼树结构 typedef struct //定义哈夫曼树的结构 { int weight; //权值 int parent; //双亲 int lchild; //左孩子 int rchild; //右孩子 }htnode,huffmantree[M+1]; 建立哈夫曼树 void crthuffmantree(huffmantree ht,int w[],int n) //初始化哈夫曼树 { int i,s1,s2,m; for(i=1;i<=n;i++) { ht[i].weight=w[i]; ht[i].parent=0; ht[i].lchild=0; ht[i].rchild=0; } m=2*n-1; for(i=n+1;i<=m;i++) { ht[i].weight=0; ht[i].parent=0; ht[i].lchild=0; ht[i].rchild=0; } for(i=n+1;i<=m;i++) { select(ht,i-1,&s1,&s2); ht[i].weight=ht[s1].weight+ht[s2].weight; ht[s1].parent=i;

数据结构实验报告(哈夫曼树)

数据结构实验报告实验题目:Huffman编码与解码 姓名: 学号: 院系:

实验名称: Huffman编码与解码实验 问题描述: 本实验需要以菜单形式完成以下功能: 1.输入电文串 2.统计电文串中各个字符及其出现的次数 3.构造哈弗曼树 4.进行哈弗曼编码 5.将电文翻译成比特流并打印出来 6.将比特流还原成电文 数据结构的描述: 逻辑结构: 本实验可用二叉树实现,其逻辑结构为一对二的形式,即一个结点对应两个结点。在实验过程中我们也应用到了栈的概念。 存储结构: 使用结构体来对数据进行存储: typedef struct { int weight; int parent,lc,rc; }HTNode,*HuffmanTree; typedef struct LNode { char *elem; int stacksize; int top; }SqStack; 在main函数里面定义一个哈弗曼树并实现上述各种功能。 程序结构的描述: 本次实验一共构造了10个函数: 1.void HuffTree(HuffmanTree &HT,int n[],int mun); 此函数根据给定的mun个权值构建哈弗曼树,n[]用于存放num个权值。 2.void Select(HuffmanTree &HT,int n,int i,int &s1,int &s2);

此函数用于在HT[1,i-1]中选择parent为0且weight为最小的两个结点,其下标分别为s1,s2. 3.void HuffmanCoding(HuffmanTree HT,char **&HC,int n); 此函数从哈弗曼树HT上求得n 个叶子结点的哈弗曼编码并存入数组HC中。 4.void Coding(HuffmanTree HT,char **HC,int root,SqStack &S); 此函数用于哈弗曼编码,先序遍历哈弗曼树HT,求得每个叶子结点的编码字符串,存入数组HC,S为一个顺序栈,用来记录遍历路径,root是哈弗曼数组HT中根结点的位置下标。 5.void InitStack(SqStack &S); 此函数用于初始化一个栈。 6.void Pop(SqStack &S,char e); 此函数为出栈操作。 7.void Push(SqStack &S,char e); 此函数为进栈操作。 8.int StackLength(SqStack S); 此函数用于求栈长,返回一个int型的值。 9.int Find(char a,char s[],int num); 此函数用于查找字符a在电文串中的位置。 10.int Recover(HuffmanTree HT,char **HC,char string[],char a[],char b[],int n); 此函数用于将比特流还原成电文。 调试分析: 输入任意一个字符串,如输入welcometoustc:运行结果如下:

数据结构实验三哈夫曼树实验报告

数据结构实验三哈夫曼树实验报告

题目:哈夫曼编/译码器 一、题目要求: 写一个哈夫曼码的编/译码系统,要求能对要传输的报文进行编码和解码。构造哈夫曼树时,权值小的放左子树,权值大的放右子树,编码时右子树编码为1,左子树编码为0. 二、概要设计: 数据结构: typedef struct { int bit[MAXBIT]; int start; } HCodeType; /* 编码结构体 */

typedef struct { int weight; int parent; int lchild; int rchild; char value; } HNode; /* 结点结构体 */ 函数: void DEMONHuffmanTree (HNode HuffNode[MAXNODE], int n) 作用:构造一个哈夫曼树,并循环构建 int main () 作用:运用已经构建好的哈弗曼树,进行节点的处理,达到成功解码编译 三、详细设计: 哈夫曼树的建立: void DEMONHuffmanTree (HNode HuffNode[MAXNODE], int n) { int i = 0, j, m1, m2, x1, x2; char x;

/* 初始化存放哈夫曼树数组HuffNode[] 中的结点*/ while (i

哈夫曼树上机实验报告

霍夫曼树 实验目的: 掌握结构体、指针及二叉树的生成、遍历等操作掌握霍夫曼编码/译码的原理。 基本要求: 熟练掌握树的操作。 程序实现: 程序第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并把树的信息保存起来,以便解压时创建同样的哈夫曼树进行解压;第二遍,根据第一遍扫描得到的哈夫曼树进行编码,并把编码后的码字存储。 要点分析: 题目中涉及的主要知识点: 1、本程序参考霍夫曼算法(由给定的权值构造赫夫曼树): (1)由给定的n个权值{w0, w1, w2, …, wn-1},构造具有n棵二叉树的集合F ={T0, T1, T2, …, Tn-1},其中每一棵二叉树Ti只有一个带有权值wi的根结点,其左、右子树均为空。 (2)重复以下步骤, 直到F中仅剩下一棵树为止:①在F中选取两棵根结点的权值最小的二叉树, 做为左、右子树构造一棵新的二叉树。置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。②在F中删去这两棵二叉树。③把新的二叉树加入F。 2、用构造赫夫曼树以完成赫夫曼编码:把d1,d2,…, dn 作为叶子

结点,把w1,w2,…,wn作为叶子结点的权,构造赫夫曼树。在赫夫曼树中结点的左分支赋0,右分支赋1,从根结点到叶子结点的路径上的数字拼接起来就是这个叶子结点字符的编码。 3、译码的过程是分解电文中的字符串,从根出发,按字符‘0’或‘1’确定找左孩子或右孩子,直至叶子节点,便求得该子串相应的字符。心得体会: 通过本次实验,我熟练掌握了结构体、指针及二叉树的生成、遍历等操作,掌握了霍夫曼编码和译码的原理,熟练掌握树的操作,尤其是对霍夫曼树有了更深刻的理解。同时,在编写代码的过程中方,对字符串的相关知识进行了回顾。

c++数据结构实验哈夫曼树

c++数据结构实验哈夫曼树

数据结构实验报告 1.实验要求 i.实验目的: (1)掌握二叉树基本操作的实现方法 (2)掌握二叉树基本操作的实现方法 (3)了解哈夫曼树的思想和相关概念 (4)学习使用二叉树解决实际问题的能力 (5)熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法,熟练改错方法。 (6)熟悉设计算法的过程 (7)进一步掌握指针、异常处理的使用 ii.实验内容: 利用二叉树结构实现赫夫曼编/解码器。 基本要求: 1、初始化(Init):能够对输入的任意长度 的字符串s进行统计,统计每个字符的频 度,并建立赫夫曼树 2、建立编码表(CreateTable):利用已经 建好的赫夫曼树进行编码,并将每个字符

的编码输出。 3、编码(Encoding):根据编码表对输入 的字符串进行编码,并将编码后的字符串 输出。 4、译码(Decoding):利用已经建好的赫 夫曼树对编码后的字符串进行译码,并输 出译码结果。 5、打印(Print):以直观的方式打印赫夫 曼树(选作) 6、计算输入的字符串编码前和编码后的 长度,并进行分析,讨论赫夫曼编码的压 缩效果。 测试数据: I love data Structure, I love Computer.I will try my best to study data structure. 提示: 1、用户界面可以设计为“菜单”方式:能够进行交互。 2、根据输入的字符串中每个字符出现 的次数统计频度,对没有出现的

字符一律不用编码。 iii.代码要求: 1、必须要有异常处理,比如删除空链表时需要抛出异常; 2、保持良好的编程的风格: 代码段与段之间要有空行和缩近 标识符名称应该与其代表的意义一致 函数名之前应该添加注释说明该函数的功能 关键代码应说明其功能 3、递归程序注意调用的过程,防止栈溢出2. 程序分析 树形结构是一种非线性结构可以用结点之间的分支来表示层次关系,二叉树是每个结点最多两个子树的有序树,十分适合计算机处理问题,而哈夫曼树是一种特殊的二叉树,它将权值大的数据放在了离根较近的结点处,这样使得带权路径长度最短,是非常好的存储方式。 2.1 存储结构 1.结点结构的存储方式:

数据结构哈夫曼树的实验报告

软件学院设计性实验报告 专业:网络工程年级/班级:2013—2014学年第一学期 一、实验目的 理解哈夫曼树的特征及其应用;在对哈夫曼树进行理解的基础上,构造哈夫曼树,并用构造的哈夫曼树进行编码和译码;通过该实验,使学生对数据结构的应用有更深层次的理解。 二、实验仪器或设备 学院提供公共机房,1台/学生微型计算机。 三、总体设计(设计原理、设计方案及流程等) 1.问题描述: 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站设计一个哈夫曼编/译码系统。 2.一个完整的系统应具有以下功能: 1)初始化(Initialzation)。从数据文件DataFile.dat中读入字符及每个字符的权值,建立哈夫曼树HuffTree; 2)编码(EnCoding)。用已建好的哈夫曼树,对文件ToBeTran.dat中的文本进行编码形成报文,将报文写在文件Code.txt中; 3)译码(Decoding)。利用已建好的哈夫曼树,对文件CodeFile.dat中的代码进行解码形成原文,结果存入文件Textfile.txt中; 4)输出(Output): 输出DataFile.dat中出现的字符以及各字符出现的频度(或概率);输出ToBeTran.dat及其报文Code.txt;输出CodeFile.dat及其原文Textfile.txt; 要求:所设计的系统应能在程序执行的过程中,根据实际情况(不同的输入)建立DataFile.dat、ToBeTran.dat和CodeFile.dat三个文件,以保证系统的通用性。 四、实验步骤(包括主要步骤、代码分析等) 1)编写C语言程序

相关文档
最新文档