文档库 最新最全的文档下载
当前位置:文档库 › 数据结构哈夫曼树和代码

数据结构哈夫曼树和代码

数据结构哈夫曼树和代码
数据结构哈夫曼树和代码

#include

#include

#include

#define N 50 //叶?子哩?结á点?数簓

#define M 2*N-1 //树骸?中D结á点?总哩?数簓

typedef struct

{

char data; //结á点?值μ

int weight; //权ü?重?

int parent; //双?亲×结á点?

int lchild; //左哩?孩¢子哩?结á点?

int rchild; //右 ?孩¢子哩?结á点?

} HTNode;

typedef struct

{

char cd[N]; //存?放?哈t夫え?曼?码?

int start;

} HCode;

HTNode ht[M];

HCode hcd[N];

int n;

void CreateHT(HTNode ht[],int n)

{

int i,k,lnode,rnode;

int min1,min2;

for (i=0;i<2*n-1;i++) //所ù有瓺结á点?的?相à关?域 ?置?初?值μ0 ht[i].parent=ht[i].lchild=ht[i].rchild=0;

printf("哈t夫え?曼?树骸?初?态?为a:\n");

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

for (i=0;i<2*n-1;i++)

{

printf("%-6c %-6d %-6d %-6d %-6d\n",ht[i].data,ht[i].weight,ht[i].parent,ht[i].lchild, ht[i].rchild);

}

for (i=n;i<2*n-1;i++) //构1造ì哈t夫え?曼?树骸?

{

min1=min2=32767; //lnode和írnode为a最?小?权ü?重?的?两?个?结á点?位?置?

lnode=rnode=0;

for (k=0;k<=i-1;k++)

if (ht[k].parent==0) //只?在ú尚 未′构1造ì二t叉?树骸?的?结á点?中D 查é找?

{

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;

ht[i].weight=ht[lnode].weight+ht[rnode].weight;

ht[i].lchild=lnode;ht[i].rchild=rnode;

}

printf("\n哈t夫え?曼?树骸?终?态?为a:\n");

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

for (i=0;i<2*n-1;i++)

{

printf("%-6c %-6d %-6d %-6d %-6d\n",ht[i].data,ht[i].weight,ht[i].parent,ht[i].lchild, ht[i].rchild);

}

printf("\n");

}

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!=0) //循-序?直±到?树骸?根ù结á点?

{

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指?向?哈t夫え?曼?编括?码?最?开a始?字?符?

hcd[i]=hc;

}

}

void DispHCode(HTNode ht[],HCode hcd[],int n) //输?出?哈t夫え?曼?编括?码?

{

int i,k;

int j;

printf("输?出?哈t夫え?曼?编括?码?:\n");

for (i=0;i

{

j=0;

printf("%c:",ht[i].data);

for (k=hcd[i].start;k<=n;k++)

{

printf("%c",hcd[i].cd[k]);

j++;

}

printf("\n");

}

}

void funsr()

{

//字?符?串?

/*int i=0;

char str[100];

printf("请?输?入?字?符?串?:");

scanf("%s",str);

int n=0;

for (int j=0;str[j]!='\0';j++)

{

int flag=0;

for(int k=0;k<=n;k++)

{

if(str[j]==ht[k].data)

{

ht[k].weight++;

flag=1;

break;

}

}

if(!flag)

{

ht[i].data=str[j];

ht[i].weight=1;

i++;

n++;

}

}*/

//单蹋?个?字?符?

int i=0;

printf("请?输?入?字?符?个?数簓n:");

scanf("%d",&n);

getchar();

for (i=0;i

{

printf("请?输?入?字?符?:");

scanf("%c",&ht[i].data);

printf("请?输?入?%c的?权ü?值μ:",ht[i].data);

scanf("%d",&ht[i].weight);

getchar();

}

printf("\n");

CreateHT(ht,n);

CreateHCode(ht,hcd,n);

DispHCode(ht,hcd,n);

}

void main()

{

funsr();

system("pause"); }

贪心算法构造哈夫曼树

软件02 1311611006 张松彬利用贪心算法构造哈夫曼树及输出对应的哈夫曼编码 问题简述: 两路合并最佳模式的贪心算法主要思想如下: (1)设w={w0,w1,......wn-1}是一组权值,以每个权值作为根结点值,构造n棵只有根的二叉树 (2)选择两根结点权值最小的树,作为左右子树构造一棵新二叉树,新树根的权值是两棵子树根权值之和 (3)重复(2),直到合并成一颗二叉树为 一、实验目的 (1)了解贪心算法和哈夫曼树的定义(2)掌握贪心法的设计思想并能熟练运用(3)设计贪心算法求解哈夫曼树(4)设计测试数据,写出程序文档 二、实验内容 (1)设计二叉树结点数据结构,编程实现对用户输入的一组权值构造哈夫曼树(2)设计函数,先序遍历输出哈夫曼树各结点3)设计函数,按树形输出哈夫曼树 代码: #include #include #include #include typedef struct Node{ //定义树结构 int data; struct Node *leftchild; struct Node *rightchild; }Tree; typedef struct Data{ //定义字符及其对应的频率的结构 int data;//字符对应的频率是随机产生的 char c; }; void Initiate(Tree **root);//初始化节点函数 int getMin(struct Data a[],int n);//得到a中数值(频率)最小的数 void toLength(char s[],int k);//设置有k个空格的串s void set(struct Data a[],struct Data b[]);//初始化a,且将a备份至b char getC(int x,struct Data a[]);//得到a中频率为x对应的字符 void prin(struct Data a[]);//输出初始化后的字符及对应的频率 int n; void main() { //srand((unsigned)time(NULL));

哈夫曼树及其应用(完美版)

数据结构课程设计设计题目:哈夫曼树及其应用 学院:计算机科学与技术 专业:网络工程 班级:网络 131 学号:1308060312 学生姓名:谢进 指导教师:叶洁 2015年7 月12 日

设计目的: 赫夫曼编码的应用很广泛,利用赫夫曼树求得的用于通信的二进制编码称为赫夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是赫夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 1、熟悉树的二叉树的存储结构及其特点。 2、掌握建立哈夫曼树和哈夫曼编码的方法。 设计内容: 欲发一封内容为AABBCAB ……(共长 100 字符,字符包括A 、B 、C 、D 、E 、F六种字符),分别输入六种字符在报文中出现的次数(次数总和为100),对这六种字符进行哈夫曼编码。 设计要求: 对输入的一串电文字符实现赫夫曼编码,再对赫夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵赫夫曼树,此构造过程称为赫夫曼编码。设计实现的功能: 1.以二叉链表存储, 2.建立哈夫曼树; 3.求每个字符的哈夫曼编码并显示。

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

数据结构哈夫曼树的实现

#include #include #include #include using namespace std; typedef struct { unsigned int weight; unsigned int parent,lchild,rchild,ch; }HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表 int m,s1,s2; HuffmanTree HT; void Select(int n){ //选择两个权值最小的结点 int i,j; for(i=1;i<=n;i++){ if(!HT[i].parent){ s1 = i;break; } } for(j=i+1;j<=n;j++){ if(!HT[j].parent){ s2 = j;break; } } for(i=1;i<=n;i++){ if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i)){ s1=i; } } for(j=1;j<=n;j++){ if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j)) s2=j; } } void HuffmanCoding(HuffmanCode HC[], int *w, int n) { // w存放n个字符的权值(均>0),构造哈夫曼树HT,// 并求出n个字符的哈夫曼编码HC int i, j; char *cd; int p; int cdlen; int start; if (n<=1) return;

哈夫曼树的建立与操作

实验六哈夫曼树的建立与操作 一、实验要求和实验内容 1、输入哈夫曼树叶子结点(信息和权值) 2、由叶子结点生成哈夫曼树内部结点 3、生成叶子结点的哈夫曼编码 4、显示哈夫曼树结点顺序表 二、详细代码(内包含了详细的注释): #include using namespace std; typedef char Elemtype; struct element { int weight; Elemtype date; element* lchild,*rchild; }; class HuffmanTree { public: HuffmanTree()//构造函数 { cout<<"请输入二叉树的个数"<>count; element *s=new element[count];//s为指向数组的指针,保存指向数组的地址 for(int i=0;i>s[i].weight;

cout<<"输入第"<>s[i].date; s[i].lchild=NULL; s[i].rchild=NULL; }//以上为初始化每一个结点 element * *m=new element*[count];//m为指向数组成员的地址的指针,保存【指向数组成员地址的指针】的地址 for(int i=0;iweightweight; return1=i; } } for(int i=0;iweightweight>a) { b=m[i]->weight; return2=i; } } q=new element;//构建一棵新树 q->weight=m[return1]->weight+m[return2]->weight; q->lchild=m[return1]; q->rchild=m[return2]; m[return1]=q; m[return2]=NULL; //用新树替换原来的两子树,并置空一个数 } boot=q;//把最后取得的哈夫曼树的头结点即q赋值给boot

北邮数据结构实验3哈夫曼编码

数据结构实验报告 实验名称:实验3——哈夫曼编码 学生姓名: 班级: 班内序号: 学号: 日期:2013年11月24日 1.实验要求 利用二叉树结构实现赫夫曼编/解码器。 基本要求: 1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个 字符的频度,并建立赫夫曼树 2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每 个字符的编码输出。 3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的 字符串输出。 4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译 码,并输出译码结果。 5、打印(Print):以直观的方式打印赫夫曼树(选作) 6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼 编码的压缩效果。 2. 程序分析 2.1存储结构: struct HNode { char c;//存字符内容 int weight; int lchild, rchild, parent; }; struct HCode

{ char data; char code[100]; }; //字符及其编码结构 class Huffman { private: HNode* huffTree; //Huffman树 HCode* HCodeTable; //Huffman编码表 public: Huffman(void); void CreateHTree(int a[], int n); //创建huffman树 void CreateCodeTable(char b[], int n); //创建编码表 void Encode(char *s, string *d); //编码 void Decode(char *s, char *d); //解码 void differ(char *,int n); char str2[100];//数组中不同的字符组成的串 int dif;//str2[]的大小 ~Huffman(void); }; 结点结构为如下所示: 三叉树的节点结构: struct HNode//哈夫曼树结点的结构体 { int weight;//结点权值 int parent;//双亲指针 int lchild;//左孩子指针 int rchild;//右孩子指针 char data;//字符 }; 示意图为: int weight int parent int lchild int rchild Char c 编码表节点结构:

数据结构课程设计-哈夫曼树

嘉应学院计算机学院 实验报告 课程名称:数据结构课程设计 开课学期:2017-2018学年第2学期 班级: 指导老师: 实验题目:哈夫曼树 学号: 姓名: 上机时间:

一、实验目的 本实验的目的是通过对简单的哈夫曼编/译码系统的设计与实现来熟练掌握树形结构在实际问题中的应用。 二、实验问题描述 利用哈夫曼编码进行通信可以大大提高通信利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,此试验即设计这样的一个简单的编/译码系统。系统应该具备如下的几个功能。 1、求出各个叶子节点的权重值 输入一个字符串,统计其中各个字母的个数和总的字母个数。 2、构造哈夫曼树 统计出的字母种类为叶子结点个数,每个字母个数为相应的权值,建立哈夫曼树。 3、打印哈弗曼树的功能模块 按照一定形式打印出哈夫曼树。 4、编码 利用已经建立好的哈夫曼树进行编码。 5、译码 根据编码规则对输入的代码进行翻译并将译码。 三、实验步骤 1、实验问题分析 (1)设计一个结构体数组保存字母的类型和个数。 { ; 字母的种类 ; 字母的个数 }; (2)在构造哈夫曼树时,设计一个结构体数组保存哈夫曼树中各结点

的信息,根据二叉树的性质可知,具有n个结点的哈夫曼树共有21个结点,所以数组大小设置为21,描述结点的数据类型为: { ; 权值 ; 双亲 ; 左孩子 ; 右孩子 }; []; 定义此类型的数组 (3)求哈夫曼编码,实质上是在已经建立的哈夫曼树中,从叶子结点开始,沿着结点的双亲链表域退回到根节点,每退回一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼值,由于一个字符的哈夫曼编码是从根结点所经过的路径上各分支所组成的0、1序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码为所求编码的高位码,所以设计如下的数据类型: 10; { []; 每个结点的哈夫曼编码 ; 开始位置 }; (4)设置全局变量。 s; 为输入的字符串 0; 记录输入的字符串中字母的种类,即叶子结点个数 0; 记录字符串中字母的总个数 []叶子结点类型 2、功能(函数)设计 (1)统计字母种类和个数模块 此模块的功能为从键盘接受一个字符串,统计字符串中字母种类即结 点个数,每种字母出现次数即各叶子结点的权值。全局变量s保存输 入的字符串,将种类和个数保存到[]中。 函数原型:() 如输入的字符串是“”则显示如下。

数据结构哈夫曼树和代码

#include #include #include #define N 50 //叶?子哩?结á点?数簓 #define M 2*N-1 //树骸?中D结á点?总哩?数簓 typedef struct { char data; //结á点?值μ int weight; //权ü?重? int parent; //双?亲×结á点? int lchild; //左哩?孩¢子哩?结á点? int rchild; //右 ?孩¢子哩?结á点? } HTNode; typedef struct { char cd[N]; //存?放?哈t夫え?曼?码? int start; } HCode; HTNode ht[M]; HCode hcd[N]; int n; void CreateHT(HTNode ht[],int n) { int i,k,lnode,rnode; int min1,min2; for (i=0;i<2*n-1;i++) //所ù有瓺结á点?的?相à关?域 ?置?初?值μ0 ht[i].parent=ht[i].lchild=ht[i].rchild=0; printf("哈t夫え?曼?树骸?初?态?为a:\n"); printf("data weight parent lchild rchild\n"); for (i=0;i<2*n-1;i++) { printf("%-6c %-6d %-6d %-6d %-6d\n",ht[i].data,ht[i].weight,ht[i].parent,ht[i].lchild, ht[i].rchild); } for (i=n;i<2*n-1;i++) //构1造ì哈t夫え?曼?树骸? {

哈工大数据结构大作业——哈夫曼树生成、编码、遍历

一、问题描述 1.用户输入字母及其对应的权值,生成哈夫曼树; 2.通过最优编码的算法实现,生成字母对应的最优0、1编码; 3.先序、中序、后序遍历哈夫曼树,并打印其权值。 二、方法思路 1.哈夫曼树算法的实现 §存储结构定义 #define n 100 /* 叶子树*/ #define m 2*(n) –1 /* 结点总数*/ typedef struct { /* 结点型*/ double weight ; /* 权值*/ int lchild ; /* 左孩子链*/ int rchild ; /* 右孩子链*/ int parent; /* 双亲链*/ 优点? }HTNODE ; typedef HTNODE HuffmanT[ m ] ; /* huffman树的静态三叉链表表示*/ 算法要点 1)初始化:将T[0],…T[m-1]共2n-1个结点的三个链域 均置空( -1 ),权值为0; 2)输入权值:读入n 个叶子的权值存于T的前n 个单元 T[0],…T[n], 它们是n 个独立的根结点上的权值; 3)合并:对森林中的二元树进行n-1次合并,所产生的新 结点 依次存放在T[i](n<=i<=m-1)。每次合并分两步: (1) 在当前森林中的二元树T [0],…T[i-1]所有结点中 选取权值 最小和次最小的两个根结点T[p1]和T[p2]作为合并对象,这 里0<= p1,p2<= i –1; (2) 将根为T[p1]和T[p2]的两株二元树作为左、右子树 合并为一 株新二元树,新二元树的根结点为T[i]。即 T[p1].parent =T[p2].parent = i ,T[i].lchild= p1,

哈夫曼树的编写与输出

/******************************************/ /********* 哈夫曼树的编写与输出***********/ /******************************************/ /*用静态三叉链表实现哈夫曼树类型定义如下:*/ #define N 20 #define M 2*N-1 typedef struct { int weight; int parent; int LChild; int RChild; } HTNode,HuffmanTree[M+1]; /*select函数主体程序代码*/ void select(HuffmanTree ht,int j,& s1,& s2 ) { int i,k; int n=0; HuffmanTree rt; for(k=0;k<=j;k++) { if(ht[k].parent ==0) { rt[k]=ht[k]; n=n+1; } } for(k=0;k

int m; m=2*n-1; for(i=n+1;i<=m;i++) { ht[i]={0,0,0,0}; } /*--------初始化完毕,对应算法步鄹(1)---------*/ for(i=n+1;i<=m;i++) { int s1,s2; select(ht,i-1,&s1,$s2); ht[i].weight=ht[s1].weight +ht[s2].weight ; ht[s1].parent=i;ht[s2].parent=i; ht[i].LChild=s1;ht[i].RChild=s2; } }

完整word版数据结构课程设计:电文编码译码哈夫曼编码

福建农林大学计算机与信息学院 数据结构课程设计 设计:哈夫曼编译码器 姓名:韦邦权 专业:2013级计算机科学与技术 学号:13224624 班级:13052316 完成日期:2013.12.28

1 哈夫曼编译码器 一、需求分析 在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈夫曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和

各个叶子对应的字符的编码,这就是哈夫曼编码。哈夫曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 二、设计要求 对输入的一串电文字符实现哈夫曼编码,再对哈夫曼编码生成的2 代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。设计实现的功能: (1) 哈夫曼树的建立; (2) 哈夫曼编码的生成; (3) 编码文件的译码。 三、概要设计 哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。 在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的

武汉理工大学数据结构与算法综合实验哈夫曼树(1)

学生学号Xxx实验课成绩 学生实验报告书 实验课程名称数据结构与算法综合实验 开课学院计算机科学与技术学院 指导教师姓名xxx 学生姓名xxx 学生专业班级xxxx 2015--2016学年第2学期

实验课程名称:数据结构与算法综合实验 实验项目名称二叉树与赫夫曼图片压缩报告成绩 实验者xx专业班级xxx组别 同组者完成日期2016年5月 2日第一部分:实验分析与设计(可加页) 一、实验目的和要求 1.目的 掌握树的存储结构 掌握二叉树的三种遍历方法 掌握 Huffman树、Huffman编码等知识和应用 使用 C++、文件操作和 Huffman算法实现“图片压缩程序”专题编程。 2.要求 针对一幅 BMP 格式的图片文件,统计 256 种不同字节的重复次数,以每种字 节重复次数作为权值,构造一颗有 256 个叶子节点的哈夫曼二叉树。 利用上述哈夫曼树产生的哈夫曼编码对图片文件进行压缩。 压缩后的文件与原图片文件同名,加上后缀.huf (保留原后缀),如 pic.bmp 压 缩后 pic.bmp.huf 二、分析与设计 依据上述的实验目的与要求,可导出实现的二叉树与赫夫曼图片压缩软件的流程为: ① 读取图片文件、统计权值 ②生成 Huffman树 ③生成 Huffman编码 ④ 压缩图片文件 ⑤ 保存压缩的文件 1.数据结构的设计 记录统计 256种不同字节的重复次数使用整型数组。 int weight[256] = { 0 }; 二叉树的存储结构。使用结构体存储节点,使用数组存储树的节点,使用静态二叉链表方 式存储二叉树。 Huffman编码存储结构 struct HTNode { int weight;//权值

哈夫曼编码算法实现完整版

实验三树的应用 一.实验题目: 树的应用——哈夫曼编码 二.实验内容: 利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。 要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。 三、程序源代码: #include #include #include #include typedef struct{ char data; int weight; int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char * * HuffmanCode; void Select(HuffmanTree &HT,int n,int m) {HuffmanTree p=HT; int tmp; for(int j=n+1;j<=m;j++) {int tag1,tag2,s1,s2; tag1=tag2=32767;

for(int x=1;x<=j-1;x++)

{ if(p[x].parent==0&&p[x].weights2) //将选出的两个节点中的序号较小的始终赋给s1 { tmp=s1; s1=s2; s2=tmp;} p[s1].parent=j; p[s2].parent=j; p[j].lchild=s1; p[j].rchild=s2; p[j].weight=p[s1].weight+p[s2].weight; } } void HuffmanCoding(HuffmanTree &HT,int n,char *w1,int*w2) { int m=2*n-1; if(n<=1) return; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); HuffmanTree p=HT; for(int i=1;i<=n;i++) { p[i].data=w1[i-1]; p[i].weight=w2[i]; p[i].parent=p[i].lchild=p[i].rchild=0; } for(;i<=m;i++) { p[i].weight=p[i].parent=p[i].lchild=p[i].rchild=0; } Select(HT,n,m); ofstream outfile; //生成hfmTree文件 outfile.open("hfmTree.txt",ios::out); for (i=1;i<=m;i++)

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

《用哈夫曼编码实现文件压缩》 实验报告 课程名称数据结构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初态(每个字符的权值)

数据结构课程设计哈夫曼编码

题目:哈夫曼编码器 班级:031021班姓名:李鑫学号:03102067 完成日期:2011/12 1. 问题描述 利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个赫夫曼码的编/译码系统。 2.基本要求 一个完整的系统应具有以下功能: (1) I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中。 (2) E:编码(Encoding)。利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 (3) D:译码(Decoding)。利用已建好的赫夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。 以下为选做: (4) P:印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。 (5) T:印赫夫曼树(Tree printing)。将已在内存中的赫夫曼树以直观的方式(比如树)显示在终端上,同时将此字符形式的赫夫曼树写入文件TreePrint 中。 3.测试 (1)利用教科书例6-2中的数据调试程序。 (2) 用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:“THIS PROGRAME IS MY FA VORITE”。 字符 A B C D E F G H I J K L M 频度186 64 13 22 32 103 21 15 47 57 1 5 32 20 字符N O P Q R S T U V W X Y Z 频度57 63 15 1 48 51 80 23 8 18 1 16 1 4.实现提示 (1) 编码结果以文本方式存储在文件Codefile中。 (2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。请用户键入一个选择功能符。此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。 (3) 在程序的一次执行过程中,第一次执行I,D或C命令之后,赫夫曼树已经在内存了,不必再读入。每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。

数据结构实验三题目二_哈夫曼树

2008级数据结构实验报告 实验名称:实验三树 学生姓名: 班级: 班内序号: 学号: 日期: 20013年11月26日 1.实验要求 实验目的 通过选择下面两个题目之一进行实现,掌握如下内容: 掌握二叉树基本操作的实现方法 了解赫夫曼树的思想和相关概念 学习使用二叉树解决实际问题的能力 实验内容 利用二叉树结构实现赫夫曼编/解码器。 基本要求: 1.初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并 建立赫夫曼树 2.建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码 输出。 3.编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。 4.译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结 果。 5.打印(Print):以直观的方式打印赫夫曼树(选作) 6.计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。 2. 程序分析 哈夫曼树结点的储存结构除了二叉树所有的双亲域parents,左子树域lchild,右子树域rchild。还需要有字符域word,权重域weight,编码域code。其中由于编码是一串由0和1组成的字符串,所以code是一个字符数组。 进行哈夫曼编码首先要对用户输入的信息进行统计,将每个字符作为哈夫曼树的叶子结点。统计每个字符出现的次数(频度)作为叶子的权重,统计次数可以根据每个字符不同的ASCII 码。并根据叶子结点的权重建立一个哈夫曼树。 建立每个叶子的编码从根结点开始,规定通往左子树路径记为0,通往右子树路径记为 1.由于编码要求从根结点开始,所以需要前序遍历哈夫曼树,故编码过程是以前序遍历二叉树

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

贪心法构造哈夫曼树

实验报告 ( 2013 / 2014 学年第二学期) 学院贝尔学院 学生姓名任晓强 班级学号 Q12010218 指导教师季一木 指导单位计算机软件教学中心 日期 2014年3月12日

实验一:贪心算法构造哈夫曼树 问题简述: 两路合并最佳模式的贪心算法主要思想如下: (1)设w={w0,w1,......w }是一组权值,以每个权值作为根结点值,构造n棵只有根的 n-1 二叉树 (2)选择两根结点权值最小的树,作为左右子树构造一棵新二叉树,新树根的权值是两棵子树根权值之和 (3)重复(2),直到合并成一颗二叉树为止 一、实验目的 (1)了解贪心算法和哈夫曼树的定义 (2)掌握贪心法的设计思想并能熟练运用 (3)设计贪心算法求解哈夫曼树 (4)设计测试数据,写出程序文档 二、实验内容 (1)设计二叉树结点数据结构,编程实现对用户输入的一组权值构造哈夫曼树 (2)设计函数,先序遍历输出哈夫曼树各结点 (3)设计函数,按树形输出哈夫曼树 三、程序源代码 #include #include #include #include typedef struct Node{ //定义树结构 int data; struct Node *leftchild; struct Node *rightchild;

}Tree; typedef struct Data{ //定义字符及其对应的频率的结构int data;//字符对应的频率是随机产生的 char c; }; void Initiate(Tree **root);//初始化节点函数 int getMin(struct Data a[],int n);//得到a中数值(频率)最小的数void toLength(char s[],int k);//设置有k个空格的串s void set(struct Data a[],struct Data b[]);//初始化a,且将a备份至b char getC(int x,struct Data a[]);//得到a中频率为x对应的字符void prin(struct Data a[]);//输出初始化后的字符及对应的频率 int n; void main() { //srand((unsigned)time(NULL)); Tree *root=NULL,*left=NULL,*right=NULL,*p=NULL; int min,num; int k=30,j,m; struct Data a[100]; struct Data b[100]; int i;

数据结构 哈夫曼编码 实验报告

数据结构实验报告 实验名称:实验3——树(哈夫曼编/解码器) 学生姓名: 班级: 班内序号: 学号: 日期:2011年12月5日 1.实验要求 利用二叉树结构实现哈夫曼编/解码器。 基本要求: 1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频 度,并建立哈夫曼树 2、建立编码表(CreateTable):利用已经建好的哈夫曼树进行编码,并将每个字符的 编码输出。 3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输 出。 4、译码(Decoding):利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出 译码结果。 5、打印(Print):以直观的方式打印哈夫曼树(选作) 计算输入的字符串编码前和编码后的长度,并进行分析,讨论哈夫曼编码的压缩效果。 并用I love data Structure, I love Computer。I will try my best to study data Structure.进行测试。 2. 程序分析 哈夫曼树结点的存储结构包括双亲域parent,左子树lchild,右子树rchild,还有字符word,权重weight,编码code 对用户输入的信息进行统计,将每个字符作为哈夫曼树的叶子结点。统计每个字符出现的次数作为叶子的权重,统计次数可以根据每个字符不同的ASCII码,根据叶子结点的权重建立一个哈夫曼树。 建立每个叶子的编码从根结点开始,规定通往左子树路径记为0,通往右子树路径记为1。由于编码要求从根结点开始,所以需要前序遍历哈夫曼树,故编码过程是以前序遍历二叉树为基础的。同时注意递归函数中能否直接对结点的编码域进行操作。 编码信息只要遍历字符串中每个字符,从哈夫曼树中找到相应的叶子结点,取得相应的编码。最后再将所有找到的编码连接起来即可。 译码则是将编码串从左到右逐位判别,直到确定一个字符。这就是哈夫曼树的逆过程。

相关文档
相关文档 最新文档