当前位置:文档之家› 哈夫曼树+心得

哈夫曼树+心得

哈夫曼树+心得
哈夫曼树+心得

一、目的与要求

1)熟练掌握Huffman树的创建算法与实现;

2)熟练掌握Huffman编码算法的实现与应用;

3)创建较为实用的通信报文Huffman编码系统和译码系统;

4)按照实验题目要求独立正确地完成实验内容(提交程序清单及相关实验数据与运行结果);

二、实验内容

构造通信报文编码和译码系统(要求Huffman编码与译码)。条件:

1、使用英文报文实施通信。设组成报文的字符集为键盘上可以输入的一共94个不同字符。

2、字符集中每个字符(含字母和两个标点符号)的使用概率自己根据英文行文合理给出。

3、以字符集中各个字符为叶结点、字符的使用频率为权重构造Huffman树,并求得各个字符的Huffman编码(参考教材P147教材算法6.12)。同时,输出构造的Huffman树和字符编码结果。

4、在上述报文编码系统中实现译码:接收报文的编码序列(即0、1字符组成的字符串,输出对应的译码报文(英文)。其中报文的编码序列自己设定,尽量是一句话或一段文字的对应编码序列,这样可以验证输出的译码是否正确。

5、实现了加密明文和解密密文。

三、实验步骤与源程序

头文件 : Hafuman.h

// 按ASCII码值初始化每个ASXII码的权值,也可以在此处修改每个ASCII码的权值

// 本例只对ASCII值从32--126共95个不同的字符进行编码

// ASCII字符 ASCII值对应在数组a中的下标

// 空格 : 32 0

// ! : 33 1

// " : 34 2

// # : 35 3

// $ : 36 4

// % : 37 5

// & : 38 6

// ' : 39 7

// ( : 40 8

// ) : 41 9

// * : 42 10

// + : 43 11

// , : 44 12

// - : 45 13

// . : 46 14

// / : 47 15

// 0--9 : 48--57 16--25

// ; : 59 27

// < : 60 28

// = : 61 29

// > : 62 30

// ? : 63 31

// ` : 64 32

// A--Z : 65--90 33--58

// [ : 91 59

// \ : 92 60

// ] : 93 61

// ^ : 94 62

// _ : 95 63

// ` : 96 64

// a--z : 97--122 65--90

// { : 123 91

// | : 124 92

// } : 125 93

// ~ : 126 95

//数组 a 存放每个不ASCII码的权值,默认为ASCII值,也可以在这里修改相应的ASCII码的权值int a[95]={ \

32, 33, 34, 35, 36, 37, 38, 39, 40, 41, \

42, 43, 44, 45, 46, 47, 48, 49, 50, 51, \

52, 53, 54, 55, 56, 57, 58, 59, 60, 61, \

62, 63, 64, 65, 66, 67, 68, 69, 70, 71, \

72, 73, 74, 75, 76, 77, 78, 79, 80, 81, \

82, 83, 84, 85, 86, 87, 88, 89, 90, 91, \

92, 93, 94, 95, 96, 97, 98, 99, 100, 101, \

102, 103, 104, 105, 106, 107, 108, 109, 110, 111, \

112, 113, 114, 115, 116, 117, 118, 119, 120, 121, \

122, 123, 124, 125, 126 \

};

typedef int ElemType;

typedef struct Hcode

{

char character;

int quan; // 与ASCII码对应的权值

int code[95]; // 与ASCII码对应的编码

}Hcode;

/*******************************哈夫曼树的结点类定义******************************/ class HBTreeNode

{

HBTreeNode *left; // 左子树指针

HBTreeNode *right; // 右子树指针

char character; // 标志ASCII码字符

public:

int hdata; // 数据域,权值

// 构造函数

HBTreeNode()

{

left=NULL;

right=NULL;

character = NULL;

}

// 带参数初始化的构造函数

HBTreeNode(ElemType item,HBTreeNode *left1,HBTreeNode *right1,char cha)

{

hdata=item;

left=left1;

right=right1;

character = cha;

}

friend class HBinaryTree; // 哈夫曼树类为结点类的友元类

};

/**********************************哈夫曼树的类定义*******************************/

class HBinaryTree

{

private:

HBTreeNode *hroot; // 哈夫曼数根结点

Hcode hcode[95]; // 存放每个ASCII码相对应信息

public:

//构造函数

HBinaryTree() { hroot = NULL; }

// 创建哈夫曼树

void HafumanCreate();

// 明文输入,flag为 0 时以键盘方式输入,为 1 时来自文件

void Hafuman_Input_Ming(int flag);

// 明文加密为密文

void Hafuman_Ming_to_Mi(char hstring_ming[]);

// 密文输入,flag为 0 时以键盘方式输入,为 1 时来自文件

void Hafuman_Input_Mi(int flag);

// 密文解密为明文

void Hafuman_Mi_to_Ming(char mi_code[]);

// 修改ASCII码权值

// 按ASCII字符编码顺序输出95个ASCII码的编码

void HafumanASCII();

// 根据哈夫曼树先序遍历每个叶子的编码

void HufumanCode();

// 根据哈夫曼树先序遍历每个叶子的编码的递归函数,len初始化为0,flag为0时先序遍历,为1时存储编码

void PutCode(HBTreeNode *&HBT,int len,int flag);

// 用于清除哈夫曼树的递归函数,被函数~HBinaryTree调用

void Clear(HBTreeNode *&HBT);

// 析构函数,清除哈夫曼树

~HBinaryTree();

};

/**************************************哈夫曼树*********************************/

// 创建哈夫曼树

void HBinaryTree::HafumanCreate()

{

int i,j;

HBTreeNode **b,*q;

b=(HBTreeNode **)malloc( 95*sizeof(HBTreeNode *) );

for(i=0;i<95;i++)

{

hcode[i].character = i+32;

hcode[i].quan = a[i];

for(int j=0;j<95;j++)

hcode[i].code[j] = 9;

b[i] = (HBTreeNode *)malloc( sizeof(HBTreeNode) );

b[i]->hdata = a[i];

b[i]->character = i + 32;

b[i]->left = b[i]->right = NULL;

}

for(i=1;i<95;i++) // 进行 n-1 次循环建立哈夫曼树

{

// 用 k1 指向森林中具有最小权值的树根结点的下标

// 用 k2 指向森林中具有次最小权值的树根结点的下标

int k1 = -1,k2; // 让 k1 初始化指向森林中的第一棵树, k2 初始化指向森林中的第二棵树for(j=0;j<95;j++)

{

if(b[j]!=NULL && k1==-1)

{

k1=j;

continue;

}

{

k2=j;

break;

}

}

// 从当前森林中求出最小权值树和次小权值树

for(j=k2;j<95;j++)

{

if(b[j]!=NULL)

{

if(b[j]->hdatahdata)

{

k2=k1;

k1=j;

}

else if(b[j]->hdatahdata)

k2=j;

}

}

// 由最小权值树和次最小权值树建立一颗新树,q指向树根结点

q=(HBTreeNode *)malloc( sizeof(HBTreeNode) );

q->hdata=b[k1]->hdata + b[k2]->hdata;

q->left=b[k1];

q->right=b[k2];

// 将指向新树的指针赋给 b 指针数组中 k1 位置, k2 位置为空b[k1]=q;

b[k2]=NULL;

}

hroot = q;

free(b);

PutCode(hroot,0,1);

}

// 明文输入,flag为 0 时以键盘方式输入,为 1 时来自文件

void HBinaryTree::Hafuman_Input_Ming(int flag)

{

int i;

char hstring_ming[10000]; // 存放原始明文,最大值为10000个字符for(i=0;i<10000;i++)

hstring_ming[i]=NULL;

if(flag == 0) // 键盘输入

{

puts("请输入原始明文: ");

char temp;

for(i=0; ( temp=getchar() ) != '\n'; i++ )

Hafuman_Ming_to_Mi(hstring_ming);

}

else // 来自文件

{

FILE * FP;

char FN[128]; // 存放文件路径

cout<<"请输入文件路径: ";

cin>>FN;

if( (FP=fopen(FN,"r+t"))==NULL )

{

cout<<"打开文件 "<

}

else

{

fread(hstring_ming,sizeof(char),10000,FP);

fclose(FP);

Hafuman_Ming_to_Mi(hstring_ming);

}

}

}

// 明文加密为密文

void HBinaryTree::Hafuman_Ming_to_Mi(char hstring_ming[])

{

int i;

char mi_code[10000]; // 暂时存放由明文经过加密的密文

int mi_count=0;

cout<<"加密后的密文:"<

int line = 0;

int temp_int;

i = 0;

while(hstring_ming[i]!=NULL)

{

temp_int = hstring_ming[i];

temp_int = temp_int - 32;

int j = 0;

cout<

while(hcode[temp_int].code[j]!=9)

{

cout<

if(mi_count<10000) // 是否超过容量

mi_code[mi_count++]=hcode[temp_int].code[j]+48;

j++;

line++;

}

{

cout<

line = 0;

}

i++;

}

cout<

int flag_open=1;

do

{

cout<<"密文是否保存(Y/N): ";

char temp_mi;

cin>>temp_mi;

if(temp_mi=='Y'||temp_mi=='y')

{

char FN[128];

cout<<"请输入要保存的文件路径名: ";

cin>>FN;

FILE * FP;

if( (FP=fopen(FN,"w+t"))==NULL )

{

cout<<"打开文件 "<

flag_open=0;

}

else

{

fwrite(mi_code,sizeof(char),mi_count,FP);

flag_open=1;

fclose(FP);

}

}

else

break;

}while(flag_open==0);

}

// 密文输入,flag为 0 时以键盘方式输入,为 1 时来自文件

void HBinaryTree::Hafuman_Input_Mi(int flag)

{

int i;

char mi_code[10000]; // 存放原始密文,0-1 的字符串,最大值为10000个字符for(i=0;i<10000;i++)

mi_code[i]=NULL;

if(flag == 0) // 键盘输入

{

char temp;

for(i=0; ( temp=getchar() ) != '\n'; i++ )

mi_code[i] = temp;

Hafuman_Mi_to_Ming(mi_code);

}

else // 来自文件

{

FILE * FP;

char FN[128]; // 存放文件路径

cout<<"请输入文件路径: ";

cin>>FN;

if( (FP=fopen(FN,"r+t"))==NULL )

{

cout<<"打开文件 "<

}

else

{

fread(mi_code,sizeof(char),10000,FP);

fclose(FP);

Hafuman_Mi_to_Ming(mi_code);

}

}

}

// 密文解密为明文

void HBinaryTree::Hafuman_Mi_to_Ming(char mi_code[]) {

int i;

char hstring_ming[10000]; // 存放密文经过翻译后的明文for(i=0;i<10000;i++)

hstring_ming[i]=NULL;

int ming_count=0; // 计算明文长度

for(int k=0,j=0;k<95;k++) // 对密文进行解密

{

int temp_j = j;

int m = 0;

while(mi_code[j] != NULL && hcode[k].code[m]!=9) {

if( (mi_code[j]-48)==hcode[k].code[m] )

{

j++;

m++;

}

else

break;

}

}

if(hcode[k].code[m]==9)

{

hstring_ming[ming_count++]=hcode[k].character;

k=-1;

}

else

{

j = temp_j;

}

if(mi_code[j]==NULL) // 密文结束

break;

}

cout<<"解密后的明文:"<

for(i=0;i

{

cout<

}

cout<

int flag_open=1;

do

{

cout<<"明文是否保存(Y/N): ";

char temp_ming;

cin>>temp_ming;

if(temp_ming=='Y'||temp_ming=='y')

{

char FN[128];

cout<<"请输入要保存的文件路径名: ";

cin>>FN;

FILE * FP;

if( (FP=fopen(FN,"w+t"))==NULL )

{

cout<<"打开文件 "<

flag_open=0;

}

else

{

fwrite(hstring_ming,sizeof(char),ming_count,FP);

flag_open=1;

fclose(FP);

}

}

break;

}while(flag_open==0);

}

// 修改ASCII码权值

void HBinaryTree::HafumanChange()

{

cout<<"请输入要修改权值的ASCII码字符: ";

char temp_char;

cin>>temp_char;

cout<<"请输入 "<

int temp_int;

cin>>temp_int;

int change = temp_char-32;

a[change] = temp_int;

Clear(hroot);

HafumanCreate(); // 重新创建哈夫曼树

}

// 按ASCII字符编码顺序输出95个ASCII码的编码void HBinaryTree::HafumanASCII()

{

cout<<"ASCII字符 ASCII码值权值"<

for(int i=0;i<95;i++)

{

int j = 0;

char temp = i+32;

cout<

while(hcode[i].code[j]!=9)

{

cout<

j++;

}

cout<

}

}

// 根据哈夫曼树先序遍历每个叶子的编码

void HBinaryTree::HufumanCode()

{

cout<<"先序遍历哈夫曼树叶子结点编码: "<

}

// 根据哈夫曼树先序遍历每个叶子的编码的递归函数,len初始化为0,flag为0时先序遍历,为1时存储编码

void HBinaryTree::PutCode(HBTreeNode *&HBT,int len,int flag)

{

static int a[20];

if(HBT!=NULL)

{

// 访问到叶子结点时输出其保存在数组a中的0和1序列编码

if(HBT->left == NULL && HBT->right == NULL)

{

int i;

if(flag==0)

{

int t_int;

t_int = HBT->character;

cout<character<

}

int temp_int;

for(i=0;i

{

if( flag == 0 ) // flag为0,先序输出编码

cout<

temp_int = HBT->character;

hcode[temp_int-32].code[i] = a[i]; // 存储与ASCII码对应的编码值}

if( flag == 0 )

cout<

}

else

{

a[len] = 0;

PutCode(HBT->left,len+1,flag);

a[len] = 1;

PutCode(HBT->right,len+1,flag);

}

}

}

// 析构函数,清除哈夫曼树

HBinaryTree::~HBinaryTree()

{

Clear(hroot);

}

// 用于清除哈夫曼树的递归函数

void HBinaryTree::Clear(HBTreeNode *&HBT)

if(HBT!=NULL)

{

// 当二叉树非空时进行如下操作

Clear(HBT->left); // 删除左子树

Clear(HBT->right); // 删除右子树

delete HBT; // 删除根结点

HBT=NULL;

}

}

源文件:Hafuman.cpp

#include

#include

#include

#include

#include

#include "Hafuman.h"

int main(void)

{

HBinaryTree HBtree;

HBtree.HafumanCreate(); // 创建哈夫曼树

char option;

do

{

cout<<" 哈夫曼树演示程序\n\n";

cout<<"[1] 明文加密为密文"<

cout<<"[2] 密文解密为明文"<

cout<<"[3] 修改ASCII码权值"<

cout<<"[4] 按ASCII字符编码顺序输出编码"<

cout<<"[5] 先序遍历哈夫曼树叶子的编码"<

cout<<"[6] 退出"<

cout<<"1--6 请选择: ";

cin>>option;

cout<

switch(option)

{

case '1': // 明文加密为密文

{

char option1;

do

{

cout<<"[1] 明文加密为密文"<

cout<<" [1] 键盘输入"<

cout<<" [2] 来自文件"<

cout<<" [3] 返回主菜单"<

cout<<" 1--3 请选择: ";

cin>>option1;

cout<

switch(option1)

{

case '1': // 键盘输入

{

HBtree.Hafuman_Input_Ming(0);

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '2': // 来自文件

{

HBtree.Hafuman_Input_Ming(1);

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '3': // 返回主菜单

{

break;

}

default:

{

cout<<"您的选择超出范围,请重新选择"<

cout<<"\npress any key to continue";

cin.get();

cin.get();

}

}

cout<<"\n\n\n\n\n\n\n\n\n\n";

cout<<"\n\n\n\n\n\n\n\n\n\n";

}while(option1!='3');

break;

}

case '2': // 密文解密为明文

{

char option2;

do

cout<<"[2] 密文解密为明文"<

cout<<" 请选择输入方式"<

cout<<" [1] 键盘输入"<

cout<<" [2] 来自文件"<

cout<<" [3] 返回主菜单"<

cout<<" 1--3 请选择: ";

cin>>option2;

cout<

switch(option2)

{

case '1': // 键盘输入

{

HBtree.Hafuman_Input_Mi(0);

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '2': // 来自文件

{

HBtree.Hafuman_Input_Mi(1);

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '3': // 返回主菜单

{

break;

}

default:

{

cout<<"您的选择超出范围,请重新选择"<

cout<<"\npress any key to continue";

cin.get();

cin.get();

}

}

cout<<"\n\n\n\n\n\n\n\n\n\n";

cout<<"\n\n\n\n\n\n\n\n\n\n";

}while(option2!='3');

break;

}

case '3': // 修改ASCII码权值

{

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '4': // 按ASCII字符编码顺序输出编码

{

HBtree.HafumanASCII();

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '5': // 先序遍历哈夫曼树叶子的编码

{

HBtree.HufumanCode();

cout<<"\npress any key to continue";

cin.get();

cin.get();

break;

}

case '6': // 退出

{

break;

}

default:

{

cout<<"您的选择超出范围,请重新选择"<

cout<<"\npress any key to continue";

cin.get();

cin.get();

}

}

if(option!='6')

{

cout<<"\n\n\n\n\n\n\n\n\n\n";

cout<<"\n\n\n\n\n\n\n\n\n\n";

}

}while(option!='6');

return 0;

}

1.编译后,运行得到顺序表的主界面如图1所示。

图1 顺序表的主界面

2.中选择1后,界面如图2所示。

—>将明文加密为密文

图2

3.继续选择主菜单下的分菜单,选择步骤1,并输入原始明文,界面如图3示。

图3 4.选择是否保存,并输入文件路径,界面如图4示。

图4 5.显示文件所在位置及内容显示,界面如图5所示。

图5 6.返回主菜单,实现步骤2操作,界面如图6所示。

图6 7. 步骤7,输入文件路径,界面如图7所示。

图7 8.显示之前输入的明文,界面如图8所示。

图8 9.修改ASCII的码权值,步骤如图9示。

图9

10.显示修改ASCII后的,顺序输出编码,界面如图10所示。

图10

五、结果分析与实验体会

关于这次实验学习,我知道了哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上分支数目称为路径长度。树的长度是指从根结点到每一个叶子结点的路径长度之和。结点的带权路径长度为从从该结点到根结点之间的

哈夫曼树 实验报告

计算机科学与技术学院数据结构实验报告 班级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序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码位所求编码的高位码,所以设计如下数据类型:

哈夫曼树编码译码实验报告(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) 编码文件的译码。

哈夫曼树的实验报告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编码与解码 姓名: 学号: 院系:

实验名称: 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)

哈夫曼树课程设计论文

课程论文 题目:哈夫曼树及其应用课程设计报告学号: 201230210115 姓名:黄文宣 班级: 1232101 专业:信息安全 课程名称:数据结构 课程老师:王晓燕 二零一肆年一月

目录 1、课程设计的题目及简介 (3) 2、实验目的 (3) 3、设计说明 (4) 4、总体流图 (4) 5、详细设计 (5) 6、实现部分 (6) 7、测试程序 (9) 8、心得与体会 (10)

一、课程设计题目 哈夫曼树及其应用 数据的读入﹑存储,生成文件,将键盘输入的信息存入指定的文件中;设计一程序求解此问题.哈夫曼(Huffman)编码原理是一种利用二叉树实现的编码原理 建立的哈夫曼树编码,再从键盘输入二进制的编码进行译码,输出译码。 哈夫曼编码的码长是变化的,对于出现频率高的信息,编码的长度较短;而对于出现频率低的信息,编码长度较长。这样,处理全部信息的总码长一定小于实际信息的符号长度。锻炼我们的编码能力,真正理解数据结构的编码思想,并且锻炼我们的动手能力和成员间的配合,提高程序编写能力。 二、实验目的 1 熟悉树的各种存储结构及其特点。 2 掌握建立哈夫曼树和哈夫曼编码的方法及带权路径长度的计算。

三、设计说明 建立哈夫曼树,将哈夫曼树的结构定义为一个结构型的一维数组,每个元素含有四项:权值,双亲,左孩子,右孩子。哈夫曼树上进行二进制编码:往左走,编码为0,往右走,编码为1,然后将从根结点到树叶中的所有0、1排列起来,则得到该树叶的哈夫曼编码。哈夫曼编码用一个结构型的一维数组保存,每个元素包含:编码、编码的开始位置、编码所对应的字符三项。给定的权值从键盘输入,输出所建立的哈夫曼树编码,再从键盘输入二进制的编码进行译码,输出译码。 四、总体流图 哈夫曼树编码系统 初始化 编码 重新建立哈夫 曼树 译码 打印编码

实验三哈夫曼树实验报告

数据结构实验报告 实验名称:实验三树 学生姓名: 班级: 班内序号: 学号: 日期:2012年12月7号 1、实验要求 利用二叉树结构实现赫夫曼编/解码器。 基本要求: 1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频 度,并建立赫夫曼树 2、建立编码表(CreateT able):利用已经建好的赫夫曼树进行编码,并将每个字符 的编码输出。 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、根据输入的字符串中每个字符出现的次数统计频度,对没有出现的

字符一律不用编码。 2、程序分析 2.1存储结构 (1)二叉树 template class BiTree { public: BiTree(); //构造函数,其前序序列由键盘输入 ~BiTree(void); //析构函数 BiNode* Getroot(); //获得指向根结点的指针protected: BiNode *root; //指向根结点的头指针}; //声明类BiTree及定义结构BiNode Data: 二叉树是由一个根结点和两棵互不相交的左右子树构成。 二叉树中的结点具有相同数据类型及层次关系。 示意图: lchild parent rchild

哈夫曼树课程设计报告(DOC)

课程设计 题目:哈夫曼编码器 院系: 专业班级: 学号: 学生姓名: 指导教师: 2014年1月2日

课程设计需求分析报告 一、分析问题和确定解决方案 1.分析问题 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统,为这样的信息收发站写一个哈夫曼的编/译码系统。 2.确定解决方案 设计建立带权的哈夫曼树,确定哈夫曼树的类与成员函数,以及各函数之间的调用关系,采用动态数组的存储结构存储所需要的数据,通过不同的函数来实现编码,译码以及打印二进制编码、哈夫曼树,把不同的数据存入不同的txt文件中,通过主函数调用来实现功能检测。 3.输入的形式和输入值的范围 手动或者从文本中读入数据的形式初始化哈夫曼树,从键盘中或者文件中读入数据,以字母A-Z代表结点,以自然数代表权值,字符串提示使用者所要执行的操作。 4.输出的形式 在显示器界面上或者以文本的形式来实现程序调试的输出。 5.程序所能达到的功能 (1)初始化。手动输入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件WritehfmTree中,输出哈夫曼树及各字符对应的编码存于WritehfmCode;从文本中读入字符,建立哈夫曼树存于ReadhfmTree, 输出哈夫曼树及各字符对应的编码存于ReadhfmCode. (2)编码。手动输入一串大写英文字符,该字符存于WriteToBeTron中,对字符进行编码并将它存于WriteCodeFile中;从文件中读取字符编码并存于ReadCodeFile中。 (3)印代码文件。将文件ReadCodeFile以紧凑格式显示在终端上,每行50个代码。同时将

2021年哈夫曼树实验报告 (1)之令狐采学创编

实验报告 欧阳光明(2021.03.07) 实验名称 Huffman 编码 专业班级 计科三班 姓名 学号 指导教师 日期 .12.20 一、实验目的 熟练掌握二叉树应用(Huffman 编码)的基本算法实现。 二、实验内容 ● 1.对输入的一串电文字符实现Huffman 编码,再对Huffman 编码生成的代码串进行译码, 输出电文字符串。实现功能如下: ? Huffman 树的建立 ? Huffman 编码的生成 编码文件的译码 三、实验要求 设计思路: 数据结构: #define n 100 //叶子结点数 #define m 2*n1 //Huffman 树中结点总数 typedef struct { int weight; //权值 int lchild , rchild , parent; //左右孩子及双亲指针 }HTNode; //树中结点类型 typedef HTNode HuffmanTree[m+1]; //0号单元不用 主要实现函数: ? 统计字符串中字符的种类以及各类字符的个数的函数 ? 构造Huffman 树的函数 ? Huffman 编码的函数 ? 建立正文的编码文件的函数 ? 代码文件的译码函数 ? 主函数 四、实验概要设计 1)功能框图 五. 使用说明 1.运行环境:VC++ 6.0 2.首先选择主控菜单中的操作1,即建表,然后进行其它操作. 六.实验截图 Huffman 编码程序 Huffman 树的建立 从叶子到根逆向求编码Huffman 编码的生成 编码文件的译码 退出

七实验体会 1、构建哈夫曼树的关键在于找最小树;在F中选择两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,且至新的二叉树的根结点的权值为其左右子树上根结点的权值之和。 2、由于学习的不足没有实现编码文件的译码,今后会加以改进 (╯﹏╰) 3、在逆向求编码的for循环里犯了一个逻辑错误导致求出来的3、4位编码串行,尝试了多钟数据输入才找到原因所在,并加以改正,编写程序需一步一步的去调试并找到错误所在。 附源程序: #include #include #include #include typedef struct { char data; //结点字符 int weight; //结点权值 int parent,lchild,rchild; //父子结点 }HTNode,* HuffmanTree; typedef char * *HuffmanCode; void Select(HuffmanTree HT, int m, int& s1, int& s2) { int i; s1 = s2 = 1; for(i=1; i<=m; i++) { if (HT[i].parent==0) { s1=i; break; } } for(i=i+1; i<=m; i++) { if (HT[i].parent==0 && HT[s1].weight>HT[i].weight) s1=i; } for(i=1; i<=m; i++) { if(HT[i].parent==0&&i!=s1) {

哈夫曼树实验报告

哈夫曼树实验报告 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作为哈夫曼编码信息的存储。 求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,没回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值,由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路

数据结构课程设计实验报告哈夫曼树的应用

计算机学院信管专业 数据结构课程设计 题目:哈夫曼树的应用班级: 姓名:学号: 同组人姓名: 起迄日期: 课程设计地点: 指导教师: 评阅意见: 成绩评定: 评阅人:日期: 完成日期:2012年12月

目录 一、需求分析 (3) 二、概要设计 (4) 三、详细设计 (6) 四、调试分析和测试结果 (7) 五、心得体会和总结 (10) 六、参考文献 (10) 七、附录 (11)

一、需求分析 (一)实验要求 要求用到数据结构课上学到的线性表的知识,所以就要充分而清晰的理解关于线性表的知识。 要求实现的基本功能很简单,只有删除和插入,增加功能也不过是加上修改。这些在数据结构课上已经讲过,只要能够理解关于线性表的几个相关的基本算法就可以了。 问题是将输入的信息保存入文件和从文件输出。这里基本是自学的内容,而且要考虑到是否要自行选择保存的磁盘。 综上,做这个课题,要具备的知识就是线性表的基本算法,文件的保存和读取算法,必要的C或者C++知识(本次我将使用C++实现),以及丰富的程序调适经验。 (二)实验任务 一个完整的系统应具有以下功能: 功能1.从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上; 功能2.利用已经建好的哈夫曼树(如不在内存,则从文件htmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中,并输出结果,将文件CodeFile以紧凑格式先是在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrint中。 功能3.利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中,并输出结果。 (三)实验步骤 分步实施: 1)初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数; 2)完成最低要求:完成功能1; 3)进一步要求:完成功能2和3。有兴趣的同学可以自己扩充系统功能。要求: 1)界面友好,函数功能要划分好 2)总体设计应画一流程图 3)程序要加必要的注释 4) 要提供程序测试方案 5)程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。

哈夫曼树及其操作-数据结构实验报告(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是最小的。

哈夫曼编码课程设计报告

湖南科技学院 数据结构课程设计报告课题: 霍夫曼编码 专业班级:信计1202 学号:201205001239 姓名:黄思琪 指导教师: 牛志毅

1 课程设计的目的和意义 在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。 哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。 通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。

2.需求分析 课题:哈夫曼编码译码器系统 问题描述:打开一篇英文文章,统计该文章中每个字符出现的次数,然后以它们作为权值,对每一个字符进行编码,编码完成后再对其编码进行译码。问题补充:1. 从硬盘的一个文件里读出一段英语文章; 2. 统计这篇文章中的每个字符出现的次数; 3. 以字符出现字数作为权值,构建哈夫曼树 4. 对每个字符进行编码并将所编码写入文件然后对所编码进行破 译。 具体介绍:在本课题中,我们在硬盘D盘中预先建立一个xuzhimo.txt文档,在里面编辑一篇文章(大写)。然后运行程序,调用fileopen()函数读出该 文章,显示在界面;再调用tongji()函数对该文章的字符种类进行统计, 并对每个字符的出现次数进行统计,并且在界面上显示;然后以每个 字符出现次数作为权值,调用Create_huffmanTree()函数构建哈夫曼 树。然后调用Huffman_bianma()函数对哈夫曼树进行编码,调用 coding()函数将编码写入文件。

哈夫曼树实验报告

数据结构实验报告 实验名称:实验三哈夫曼树 学生姓名: 班级: 班内序号: 学号: 日期: 程序分析: 存储结构:二叉树 程序流程: 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语言程序)

哈夫曼树实验报告 需求分析: 从终端读入一串字符,利用建立好的哈夫曼树对其进行编码,储存到文件当中去,然后从文件读入哈夫曼编码,针对每个字母对其进行译码,翻译为原来的信息。 二、概要设计 程序分为以下几个模块: 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;

哈夫曼树课程设计报告

闽江学院 课程设计说明书 题目:哈夫曼编译码器 院系:计算机科学系 专业班级:10软件工程 学号: 学生姓名: 指导教师: 2011年12 月30 日

课程设计需求分析报告 一、分析问题和确定解决方案 1.分析问题 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统,为这样的信息收发站写一个哈夫曼的编/译码系统。 2.确定解决方案 设计建立带权的哈夫曼树,确定哈夫曼树的类与成员函数,以及各函数之间的调用关系,采用动态数组的存储结构存储所需要的数据,通过不同的函数来实现编码,译码以及打印二进制编码、哈夫曼树,把不同的数据存入不同的txt文件中,通过主函数调用来实现功能检测。 3.输入的形式和输入值的范围 手动或者从文本中读入数据的形式初始化哈夫曼树,从键盘中或者文件中读入数据,以字母A-Z代表结点,以自然数代表权值,字符串提示使用者所要执行的操作。 4.输出的形式 在显示器界面上或者以文本的形式来实现程序调试的输出。 5.程序所能达到的功能 (1)初始化。手动输入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件WritehfmTree中,输出哈夫曼树及各字符对应的编码存于WritehfmCode;从文本中读入字符,建立哈夫曼树存于ReadhfmTree, 输出哈夫曼树及各字符对应的编码存于ReadhfmCode. (2)编码。手动输入一串大写英文字符,该字符存于WriteToBeTron中,对字符进行编码并将它存于WriteCodeFile中;从文件中读取字符编码并存于ReadCodeFile中。 (3)译码。先初始化默认哈夫曼树,手动输入二进制代码进行译码存于WriteTextFile中;

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

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

题目:哈夫曼编/译码器 一、题目要求: 写一个哈夫曼码的编/译码系统,要求能对要传输的报文进行编码和解码。构造哈夫曼树时,权值小的放左子树,权值大的放右子树,编码时右子树编码为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 班 一、课程设计(论文)题目哈夫曼树及其编码 二、课程设计(论文)工作自 2015年 1 月 5 日起至 2015年 1 月 9日止。 三、课程设计(论文) 地点: 创新大楼303,305 四、课程设计(论文)内容要求: 1.课程设计的目的 为了配合《数据结构》课程的教学,使学生能更深刻的领会《数据 结构》课程的重要性,特开设此课程设计;编写一些在特定数据结构上的 算法,通过上机调试,更好的掌握各种数据结构及其特点,培养学生综合 运用所学理论知识解决复杂实际问题的实践能力、研究性学习能力和团队 合作能力。 2.课程设计的任务及要求 1)基本要求 (1)课程设计前必须选定课程设计题目,并认真进行需求分析与系统设 计; (2)上机调试之前要认真准备实验程序及调试时所需的测试数据; (3)独立思考,独立完成,严禁抄袭,调试过程要规范,认真记录调试 结果; (4)上机结束后认真规范撰写课设报告,对设计进行总结和讨论。 2)课程设计论文编写要求 (1)要按照书稿的规格撰写打印课设论文 (2)论文包括任务书、目录、绪论、正文、总结、参考文献、附录等 (3)正文中要有问题描述、抽象数据类型的定义、数据的存储结构、设 计的求解算法、算法的实现、调试分析与测试结果 (4)课设论文装订按学校的统一要求完成 3)课设考核 从以下几方面来考查: (1)考勤和态度;

(2)任务的难易程度及设计思路; (3)动手调试能力; (4)论文撰写的水平、格式的规范性。 4)参考文献 [1] 严蔚敏, 吴伟民. 数据结构(C语言版)[M]. 北京:清华大学出版社, 2007年. [2] 严蔚敏, 吴伟民. 数据结构题集(C语言版)[M]. 北京:清华大学出版 社, 2007年. [3] 谭浩强. C语言程序设计[M]. 北京:清华大学出版社,2006年. 5)课程设计进度安排 内容天数地点 构思及收集资料1图书馆 程序设计与调试3计算机房 撰写论文1图书馆 6)任务及具体要求 ⑴初始化:键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树; ⑵编码:利用建好的哈夫曼树生成哈夫曼编码; ⑶输出其哈夫曼树及哈夫曼编码; ⑷设字符集及频度如下表: 字符空格 A B C D E F G H I J K L M 频度 197 64 13 22 32 103 21 15 47 57 5 1 20 32 字符 N O P Q R S T U V W X Y Z 频度 57 63 1 15 48 16 80 23 8 18 1 51 1 学生签名: 年月日 课程设计(论文)评审意见 (1)考勤和态度:优()、良()、中()、一般()、差() (2)任务难易及设计思路:优()、良()、中()、一般()、差() (3)动手调试能力评价:优()、良()、中()、一般()、差() (4)论文撰写水平及规范性评价:优()、良()、中()、一般()、差() 评阅人:职称:讲师 年月日

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

数据结构实验报告实验题目: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:运行结果如下:

相关主题
文本预览
相关文档 最新文档