用哈夫曼编码实现文件压缩实验报告管理资料.docx

上传人:b****3 文档编号:3892960 上传时间:2022-11-26 格式:DOCX 页数:17 大小:238.66KB
下载 相关 举报
用哈夫曼编码实现文件压缩实验报告管理资料.docx_第1页
第1页 / 共17页
用哈夫曼编码实现文件压缩实验报告管理资料.docx_第2页
第2页 / 共17页
用哈夫曼编码实现文件压缩实验报告管理资料.docx_第3页
第3页 / 共17页
用哈夫曼编码实现文件压缩实验报告管理资料.docx_第4页
第4页 / 共17页
用哈夫曼编码实现文件压缩实验报告管理资料.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

用哈夫曼编码实现文件压缩实验报告管理资料.docx

《用哈夫曼编码实现文件压缩实验报告管理资料.docx》由会员分享,可在线阅读,更多相关《用哈夫曼编码实现文件压缩实验报告管理资料.docx(17页珍藏版)》请在冰豆网上搜索。

用哈夫曼编码实现文件压缩实验报告管理资料.docx

用哈夫曼编码实现文件压缩实验报告管理资料

 

《用哈夫曼编码实现文件压缩》

 

实验报告

 

课程名称数据结构B

实验学期2013至2014学年第一学期

学生所在系部计算机学院

年级2013专业班级

学生姓名学号

任课教师

实验成绩

一、实验题目:

用哈夫曼编码实现文件压缩

二、实验目的:

1、了解文件的概念。

2、掌握线性链表的插入、删除等算法。

3、掌握Huffman树的概念及构造方法。

4、掌握二叉树的存储结构及遍历算法。

5、利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。

三、实验设备与环境:

微型计算机、Windows系列操作系统、VisualC++

四、实验内容:

根据输入小写英文字母和输入的对应权值创建哈夫曼树,可以求出每个小写英文字母的哈夫曼编码,将文本中的字母对应的哈夫曼编码写入文本中,实现对文本的编码。

五、概要设计:

(1)构造Hufffman树的Hufffman算法

构造Huffman树步骤:

1.根据给定的n个权值{w1,w2,……wn},构造n棵只有根结点的二叉树,起权值为wj。

2.在森林中选取两棵根结点权值最小和次小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和。

3.在森林中删除这两棵树,同时将新得到的二叉树加入森林中。

重复上述两步,直到只含一棵树为止,这棵树即哈夫曼树。

算法结构如图:

(2)Huffman编码:

数据通信用的二进制编码

思想:

根据字符出现频率编码,使电文总长最短

编码:

根据字符出现频率构造Huffman树,然后将树中结点引向其左孩子的分支标“0”,引向其右孩子的分支标“1”;每个字符的编码即为从根到每个叶子的路径上得到的0、1序列。

(3)文本编码

读取存放在文本中的字母,一对一的进行编译,将对应的编码存放到另一个文本中。

六、详细设计:

#include<>

#include<>

#include<>

//树结点定义

typedefstruct

{

intweight;

intparent;

intlchild;

intrchild;

}HTNode,*HuffmanTree;

staticcharN[100];//用于保存字符

//赫夫曼编码,char型二级指针

typedefchar**HuffmanCode;

//封装最小权结点和次小权结点

typedefstruct

{

ints1;

ints2;

}MinCode;

//函数声明

voidError();

HuffmanCodeHuffmanCoding(HuffmanTree&HT,HuffmanCodeHC,int*w,intn);

MinCodeSelect(HuffmanTreeHT,intn);

//当输入1个结点时的错误提示

voidError()

{

printf("一个字符不进行编码!

\n");

exit

(1);

}

//构造赫夫曼HT,编码存放在HC中,w为权值,n为结点个数

HuffmanCodeHuffmanCoding(HuffmanTree&HT,HuffmanCodeHC,int*w,intn)

{

inti,s1=0,s2=0;

HuffmanTreep;

char*cd;

intf,c,start,m;

MinCodemin;

if(n<=1)

{

Error();//只有一个结点不进行编码,直接exit

(1)退出

}

m=2*n-1;//赫夫曼码需要开辟的结点大小为2n-1

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//开辟赫夫曼树结点空间m+1

//初始化n个叶子结点

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

{

p->weight=*w;

p->parent=0;

p->lchild=0;

p->rchild=0;

}

//将n-1个非叶子结点的初始化

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

{

p->weight=0;

p->parent=0;

p->lchild=0;

p->rchild=0;

}

//构造赫夫曼树

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

{

min=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;//赋权和

}

//打印赫夫曼树

printf("HTList:

\n");

printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n");

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

{

printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

}

//从叶子结点到根节点求每个字符的赫夫曼编码

HC=(HuffmanCode)malloc((n+1)*sizeof(char*));

cd=(char*)malloc(n*sizeof(char*));//为赫夫曼编码动态分配空间

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

//求叶子结点的赫夫曼编码

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

{

start=n-1;

//定义左子树为0,右子树为1

/*

从最下面的1号节点开始往顶部编码(逆序存放),然后编码2号节点,3号......

*/

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';

}

//为第i个字符分配编码空间

HC[i]=(char*)malloc((n-start)*sizeof(char*));

//将当前求出结点的赫夫曼编码复制到HC

strcpy(HC[i],&cd[start]);

}

free(cd);

returnHC;

}

MinCodeSelect(HuffmanTreeHT,intn)

{

intmin,secmin;

inttemp=0;

inti,s1,s2,tempi=0;

MinCodecode;

s1=1;

s2=1;

min=999999;//足够大

//找出权值weight最小的结点,下标保存在s1中

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

{

if(HT[i].weight

{

min=HT[i].weight;

s1=i;

}

}

secmin=999999;//足够大

//找出权值weight次小的结点,下标保存在s2中

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

{

if((HT[i].weight

=s1)&&HT[i].parent==0)

{

secmin=HT[i].weight;

s2=i;

}

}

//放进封装中

=s1;

=s2;

returncode;

}

voidCompression(HuffmanCodeHC)//翻译原文档字符为赫夫曼编码

{

FILE*fp1,*fp2;

charch;

if((fp1=fopen("","r"))==NULL)

exit(0);

if((fp2=fopen("","a"))==NULL)

exit(0);

ch=fgetc(fp1);

while((int)ch!

=-1)

{

switch(ch)

{

case'a':

fputs(HC[1],fp2);break;

case'b':

fputs(HC[2],fp2);break;

case'c':

fputs(HC[3],fp2);break;

case'd':

fputs(HC[4],fp2);break;

case'e':

fputs(HC[5],fp2);break;

case'f':

fputs(HC[6],fp2);break;

case'g':

fputs(HC[7],fp2);break;

case'h':

fputs(HC[8],fp2);break;

case'i':

fputs(HC[9],fp2);break;

case'j':

fputs(HC[10],fp2);break;

case'k':

fputs(HC[11],fp2);break;

case'l':

fputs(HC[12],fp2);break;

case'm':

fputs(HC[13],fp2);break;

case'n':

fputs(HC[14],fp2);break;

case'o':

fputs(HC[15],fp2);break;

case'p':

fputs(HC[16],fp2);break;

case'q':

fputs(HC[17],fp2);break;

case'r':

fputs(HC[18],fp2);break;

case's':

fputs(HC[19],fp2);break;

case't':

fputs(HC[20],fp2);break;

case'u':

fputs(HC[21],fp2);break;

case'v':

fputs(HC[22],fp2);break;

case'w':

fputs(HC[23],fp2);break;

case'x':

fputs(HC[24],fp2);break;

case'y':

fputs(HC[25],fp2);break;

case'z':

fputs(HC[26],fp2);break;

default:

printf("没有编码!

\n");

}

ch=fgetc(fp1);

}

fclose(fp1);

fclose(fp2);

}

voidmain()

{

HuffmanTreeHT=NULL;

HuffmanCodeHC=NULL;

int*w=NULL;

inti,n;

printf("输入字符:

");

gets(N);

n=strlen(N);

w=(int*)malloc((n+1)*sizeof(int*));//开辟n+1个长度的int指针空间

w[0]=0;

printf("输入结点权值:

\n");

//输入结点权值

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

{

printf("w[%d]=",i);

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

}

//构造赫夫曼树HT,编码存放在HC中,w为权值,n为结点个数

HC=HuffmanCoding(HT,HC,w,n);

//输出赫夫曼编码

printf("赫夫曼:

\n");

printf("Number\t\tWeight\t\tCode\n");

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

{

printf("%c\t\t%d\t\t%s\n",N[i-1],w[i],HC[i]);

}

Compression(HC);

}

选取权值最小的结点的算法:

选取权值次小的结点的算法:

哈夫曼树建立的算法:

开始

读入n,S1,S2的值

i=n+1

i<=2n-1

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;

i++

输出S1的值

结束

哈夫曼编码的算法:

开始

读入n

i=1

i<=n

start=1

c=i

f=HT[i].parent

f!

=0

HT[f].lchild==c

cd[--start]='1'

cd[--start]='0'

i++

输出cd的值

结束

七、测试结果及分析:

4.输出哈夫曼树:

5.字符对应编码:

6.要编码的文本:

7.编译后的文本:

 

八、教师评语:

教师评价

评定项目

A

B

C

D

评定项目

A

B

C

D

算法正确

界面美观,布局合理

程序结构合理

操作熟练

语法、语义正确

解析完整

实验结果正确

文字流畅

报告规范

题解正确

其他:

 

评价教师签名:

年月日

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1