基于哈夫曼编码的数据压缩解压程序论文

基于哈夫曼编码的数据压缩解压程序论文
基于哈夫曼编码的数据压缩解压程序论文

合肥学院

计算机科学与技术系

课程设计报告

2010~2011学年第二学期

课程C++课程设计

课程设计名称基于哈夫曼编码的数据压缩/解压程序

学生姓名龚天棚

学号1012091010

专业班级网络工程(1)班

指导教师项响琴、徐静

2011年6月

目录

一、需求分析...................................................................................................... - 3 -

1.1课程设计目的.......................................................................................... - 3 -

1.2课程设计名称及内容.............................................................................. - 3 -

1.3任务和要求............................................................................................. - 3 -

二、算法设计...................................................................................................... - 4 -

2.1设计思想:.............................................................................................. - 4 -

2.2 算法思想:............................................................................................. - 5 -

2.3 主要模块说明......................................................................................... - 5 -

2.4 部分重要函数的实现:......................................................................... - 6 -

三、用户手册...................................................................................................... - 6 -

四、测试结果...................................................................................................... - 8 -

4.1 压缩过程:........................................................................................... - 8 -

4.2 解压过程............................................................................................... - 9 -

4.3 显示文本内容......................................................................................... - 9 -

4.4 显示帮助界面:................................................................................... - 10 -

五、总结............................................................................................................ - 10 -

六、参考资料..................................................................................................... - 11 -

七、附录............................................................................................................ - 12 -

7.1源代码.................................................................................................... - 12 -

7.2 运行结果............................................................................................... - 22 -

一、需求分析

1.1课程设计目的

将理论教学中涉及到的知识点贯穿起来,对不同的数据类型、程序控制结构、数据结构作一比较和总结,结合设计题目进行综合性应用,对所学知识达到融会贯通的程度。通过课程设计,学生在下述各方面的能力应该得到锻炼:

(1)进一步巩固、加深学生所学专业课程《C++程序设计语言》的基本理论知识,理论联系实际,进一步培养学生综合分析问题,解决问题的能力。

(2)全面考核学生所掌握的基本理论知识及其实际业务能力,从而达到提高学生素质的最终目的。

(3)利用所学知识,开发小型应用系统,掌握运用C++语言编写调试应用系统程序,训练独立开发应用系统,进行数据处理的综合能力。

(4)对于给定的设计题目,如何进行分析,理清思路,并给出相应的数学模型。

(5)掌握结构化程序设计方法,熟悉面向对象程序设计方法。

(6)熟练掌握C++语言的基本语法,灵活运用各种数据类型。

(7)进一步掌握在集成环境下如何调试程序和修改程序。

1.2课程设计名称及内容

课程设计名称:基于哈夫曼编码的数据压缩/解压程序

设计内容:将任意一个指定的文本文件中的字符进行哈夫曼编码,生成一个编码文件(压缩文件);反过来,可将一个压缩文件解码还原为一个文本文件。

1.3任务和要求

1)可设计一个菜单:

Q----Quit

L----List Text Document

D----Decoding

C----Coding

2)选择C时:

输入一个待压缩的文本文件名称(可带路径)。

如:D:\lu\lu.txt

统计文本文件中各字符的个数作为权值,生成哈夫曼树;

将文本文件利用哈夫曼树进行编码,生成压缩文件。

压缩文件名称=文本文件名.COD 如:D:\lu\lu.COD

压缩文件内容=哈夫曼树的核心内容+编码序列

3) 选择D时:

输入一个待解压的压缩文件名称(可带路径 )

如:D:\lu\lu.COD

从文件中读出哈夫曼树,并利用哈夫曼树将编码序列解码;

生成(还原)文本文件。

文件文件名称=压缩文件名+"_new.txt"

如:D:\lu\lu_new.txt

4)选择L时:

输入一个待压缩的文本文件名称(可带路径)。

如:D:\lu\lu_new.txt

显示出该文本文件的内容

5)功能扩展(自己定制):

编码使用二进制位,利用位运算进行真正的数据压缩。

可对任何文件进行压缩。

显示出各种重要信息,如压缩率,各字符的哈夫曼编码表。

二、算法设计

2.1设计思想:

2.2 算法思想:

2.2.1输入要压缩的文件

首先运行的时候,用户主界面上有菜单提示该如何使用软件,根据菜单提示选择所要执行的项,依次进行,因为各个环节之间有先后顺序。第一步为输入压缩软件的名称,由键盘输入文件路径和文件名称,读入字符数组中,打开该文件,按照提示进行压缩。若打不开,则继续输入。

2.2.2读文件并计算字符频率

文件将信息存放在字符数组中;计算每个字符出现的次数,申请一个结构体数组空间,用读取的字符减去字符结束符作为下标记录字符的频率。

2.2.3根据字符的频率,利用Huffman编码思想创建Huffman树

将所记录的字符的频率作为权值来创建Huffman树,依次选择权值最小的两个字符

作为左右孩子,其和作为父结点的权值,依次进行下去,直到所有的字符结点都成为叶

子结点。

2.2.4由创建的Huffman树来决定字符对应的编码,进行文件的压缩

根据创建的Huffman树来确定个字符的01编码,左孩子为0,右孩子为1。读取文件,依次将每个字符用他们的编码表示,即完成一次编码。

2.2.5解码压缩即根据Huffman树进行译码

读取编码文件,依据创建的Huffman树,定义一个指针指向根结点。从根结点开始,每读一个字符,指针变化一次(当读取的字符是‘1’时,指针指向当前所指结点的右孩子,当读取的字符是‘0’时,指针指向当前所指结点的左孩子),直至该指针所指结点为叶子结点时结束(即当结点的左右孩子均为空时)。将当前叶子结点所代表的字符值输出到译码文件中,依次读取编码文件中的字符,按照上述方法依次进行下去直至文件

2.3 主要模块说明

下面是该系统的模块

首先定义一个结构体:

struct head

{

unsigned char b; //记录字符

long count; //权重

int parent,lch,rch; //定义双亲,左孩子,右孩子

char bits[256]; //存放哈夫曼编码的数组

}

header[512],tmp; //头部一要定设置至少512个,因为结点最多可

达256,所有结点数最多可达511 然后是实现各个功能的函数:

void show() 显示文本文件的内容

unsigned char ctoa(char a[]) 将数组的前八位转成二进制形式bit位

char *code(unsigned char temp,int leafnum) 寻找对应字符的编码串,并返回 void compress(char *infilename,char *outfilename) 对文本编码函数

void uncompress(char *infiname,char *outfilename) 对压缩文件解码void ctoa(unsigned char a,char code[]) 字符转为二进制形式存入8位数组

int strcmp1(char buf[],struct head head[],int n,unsigned char &c)

将buf字符串与header[i].bits[]中匹配,成功后对应的字符由c带回

void strcpy1(char buf[],char a[],int)

将字符串a中长度为j的部分复制到buf数组中

最后是主函数:

在主函数中含有菜单函数void MainMenu()和帮助函数void help(),最后通过switch语句,调用各种函数,分别完成各自的功能。

2.4 部分重要函数的实现:

void compress(char *infilename,char *outfilename)的实现:

1)记录文件中字符频度;

2)根据频度建树;

3)根据哈夫曼树编码;

4)对文件进行编码,写入新文件(核心);

5)将字符编码对照表写入文件;

6) 将文件的哈夫曼编码输出到显示器上。

void compress(char *infilename,char *outfilename)的实现:

1)读入必要的数据;

2)读入编码对照表,放入header[i].bits[]数组中;

3)对读入的编码对照表进行排序,长度短的排在前面;

4) 将编码读入内容,进行解码工作。

三、用户手册

运行后的主界面会提示用户进行想要的操作。

1)编码(压缩文件)操作。

若用户想要对某一文件进行压缩,则按主界面的提示按“C”,然后界面提示输入进行压缩操作的文件路径和文件名,输入完成后按回车键,此时界面会提示输入压缩后文件的保存路径及其文件名,输入完成后再按回车键,便可完成编码,同时会显示出各字符的哈夫曼编码,系统也会提示用户压缩文件过程结束。

2)译码(还原文件)操作

若用户想对某一压缩文件进行解压操作,则按主界面的提示按“D”,然后界面提示输入进行解压操作的文件路径和文件名,完成输入后按回车键,此时界面会提示输入解压后的文件的保存路径及其文件名,输入完成后再按回车键,便可完成译码,系统提示用户还原文件过程结束。

3)显示数据内容

若用户想知道文本输入的内容,可输入“L”,然后界面提示输入文本文件的路径和文件名,完成输入后按回车键,界面会出现文本的内容。

4)帮助操作

若用户不知道怎么使用该软件,则按主界面的提示按“H”,然后界面会出现教您怎么使用该软件的界面。

5)操作失败后的界面提示,若用户输入的文件路径和文件名错误,则界面会提示用户输出文件打开失败。

用户根据需求,在操作过程中按“Q”可随时退出系统。

四、测试结果

4.1 压缩过程:

在D盘中建立一个文本文档,并命名为123.txt。

通过程序编译:

在D盘中生成一个.COD的文档,并且名为123_new.COD:

4.2 解压过程

解压过程就是将刚才压缩的文本文件还原。

通过程序编译:

在D盘生成一个.txt的文件,并且名为456.txt,同时文本的内容与原来的文本信息相同,实现解压功能。

4.3 显示文本内容

将文本的内容输出在显示器上

通过程序编译过后:

4.4 显示帮助界面:

五、总结

在当今信息时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

在课程设计过程中,我选择了《基于哈夫曼编码的数据压缩与解压程序》这一课题,虽然这个课题所涉及的知识我们还没有学习到,属于数据结构与算法的内容,但通过借助书本,自己动手实践,还是掌握了一点关于数据结构的知识,通过一周的课程设计使我对哈夫曼树以及哈夫曼编码有了更深的认识和理解,利用哈夫曼编码的思想方法,熟练掌握哈夫曼编码的过程。创建二叉树的方法和二叉树的存储结构,知道压缩文件是如何进行的,解压缩即为它的逆过程。程序的模块化结构尤其重要,应掌握各个模块间的逻辑关系和整体程序的结构。

其实在这次课程设计中遇到很多问题,第一就是知识没有学到,必须从最基本的书本知识看起,谢谢指导老师借给我的那本数据结构与算法的课本,对我帮助很大,

使我对程序的一些算法有了最基本的了解。其次通过网络资源使我了解的知识更加丰富,增强了我对网络资源的检索能力,使我能够更好的应用网络资源来完成自己需要完成的任务。所以课程设计不仅能培养我们的专业知识,而且还能培养我们的动手能力,使我们以后能够更加适应社会的发展。

通过这次课程设计,使我的自学能力有所提高,让我知道了怎么去接受一个新的知识并且能够很好的掌握它。同时也增强我的独立思考能力和动手能力;通过编写程序代码和调试运行,我们可以逐步积累调试程序的经验,逐渐培养我们的编程能力和利用计算机解决实际问题的能力。课程设计为我们提供了一个自己动手实践的平台。

另一方面,在课程设计的过程中,使我明白了面向对象与面向对象的差别。在面向对象过程中,类的设计是至关重要的,类设计好了等于程序就成功了一半,所以这次的课程设计帮助我复习了这一学期面向对象课程的学习,刚好可以弥补这一学期面向对象学习的不足。同时,也使我对数据结构与算法的知识有了一定的了解,帮我在大二学习数据结构与算法的课程中奠定了一定的基础,使我以后学习数据结构与算法的时候可以更加轻松。

这次课程设计不但使我掌握了一些知识,更重要的是使我认识到了作为程序员的艰辛和辛苦。一个星期面对着电脑,在你面前只有一行行的代码,在你的耳旁只有键盘的敲击声和点击鼠标的声音,说实话确实很无聊也很辛苦。但当自己看到自己编写的程序顺利通过的时候,心里的成就感就油然而生,心中的疲倦也消失了,我想,当程序员看到自己的程序能够编译成功的话,也是这种感觉吧!

虽然这次课程设计结束了,但我们学习C++等语言的步伐不能停止,在今后的学习过程中,我会更加努力,争取在今后的课程中学得更好,下次的课程设计能够更加成功。

六、参考资料

[1].郑莉等编著《C++语言程序设计(第三版)》北京:清华大学出版社

[2].郑莉等编著《C++语言程序设计(第三版)学生用书》北京:清华大学出版社

[3].李春葆等编著《C++程序设计学习与上机实验指导》北京:清华大学出版社

[4].范辉等编著《Visual C++6.0程序设计简明教程》高等教育出版社

[5].李龙澍《C++程序设计实训教程》北京:清华大学出版社

[6].洪国胜等编著《C++ Builder程序设计轻松上手》北京:清华大学出版社

[7].严蔚敏等《数据结构(c语言版)》北京:清华大学出版社,1997年4月第1版

[8].胡学钢等《数据结构算法设计指导》北京:清华大学出版社,1999年第1版

[9] . 郑莉等编著《C++语言程序设计(第4版)学生用书》北京:清华大学出版社

[10].苏小红等编著《C语言大学实用教程》北京:电子工业出版社

[11].王昆仑等编著《数据结构域算法(高等学校计算机精品课程系列教材)》中国铁道工

业出版社

七、附录

7.1源代码

#include

#include

#include

#include

#include

using namespace std;

struct head

{

unsigned char b; //记录字符

long count; //权重

int parent,lch,rch; //定义双亲,左孩子,右孩子

char bits[256]; //存放哈夫曼编码的数组

}

header[512],tmp; //头部一要定设置至少512个,因为结点最多可达256,所有结点数最多可达511

unsigned char ctoa(char a[]) /*将数组的前八位转成二进制形式比特位*/

{

unsigned char c=0;

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

if(a[i]!=0)

{

c=c+(int)(a[i]-'0')*pow(2,8-1-i);

}

return c;

}

char *code(unsigned char temp,int leafnum) //寻找对应字符的编码串,并返回

{

for(int i=0;i

if(temp==header[i].b)

return header[i].bits;

return NULL;

}

void compress(char *infilename,char *outfilename)

{

long flength=0; //记录压缩前文件长度long clength=8; //编码从偏移量8记录,统计压缩后编码长度加8

int leafnum; //定义叶子结点

int pointnum; //定义总结点

unsigned char temp; //定义unsigned char类型,暂存文件中字符的中间变量

/*********************************文件中字符频度************************************/

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

{

header[i].count=0; //初始化权重

header[i].b=(unsigned char)i; //初始化字符

}

ifstream infile(infilename,ios::in|ios::binary);

while(infile.peek()!=EOF)

{

infile.read((char *)&temp,sizeof(unsigned char)); //读入一个字符

header[temp].count++; //统计对应结点字符权重

flength++; //统计文件长度

}

infile.close(); //关闭文件

for(i=0;i<256-1;i++) //对结点进行冒泡排序,权重大的放在上面,编码时效率高for(int j=0;j<256-1-i;j++)

if(header[j].count

{

tmp=header[j];

header[j]=header[j+1];

header[j+1]=tmp;

}

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

if(header[i].count==0) break;

leafnum=i; //取得哈夫曼树中叶子结点数

pointnum=2*leafnum-1; //取得哈夫曼树中总结点数目

/**********************************根据频度建树*************************************/

long min; //尽量用long,如果文件过大,这里建树可能不是最优树了

int s1,s2;

for(i=leafnum;i

{

min=999999999;

for(int j=0;j

if(header[j].parent==0&&header[j].count

{

min=header[j].count;

s1=j;

}

header[s1].parent=i; //填写第一个叶子结点信息

min=999999999;

for(j=0;j

if(header[j].parent==0&&header[j].count

{

min=header[j].count;

s2=j;

}

header[s2].parent=i;

header[i].count=header[s1].count+header[s2].count; //填写父结点信息

header[i].lch=s1;

header[i].rch=s2;

}

/*********************************根据哈夫曼树编码**********************************/

char tmp[256]; //定义临时变量,暂存编码

tmp[255]='\0'; //添加结束标志

int start;

int c; //记录当前叶结点下标

int f; //存储父结点的下标

for(i=0;i

{

start=255; //另开始等于数组最后位

for(c=i,f=header[i].parent;f!=0;c=f,f=header[f].parent) //对叶结点进行编码

if(header[f].lch==c) tmp[--start]='0';

else tmp[--start]='1';

strcpy(header[i].bits,&tmp[start]);

}

/************************************对文件进行编码,写入新文件(核心)*********************************/

infile.open(infilename,ios::in|ios::binary); //打开待压缩的文件

infile.clear();

infile.seekg(0);

ofstream outfile(outfilename,ios::out|ios::binary); //打开压缩后将生成的文件

outfile.write((char *)&flength,sizeof(long)); //写入原文件长度

char buf[513]="\0"; //初始化编码缓冲区

outfile.seekp(8); //指针定向偏移量8

while(infile.peek()!=EOF)

{

infile.read((char *)&temp,sizeof(unsigned char)); //读入字符

strcat(buf,code(temp,leafnum)); //检索出字符对应编码,连到buf[]中

while(strlen(buf)>=8) //当buf中字符长度大于8时,一直处理写入,直至小于8 {

temp=ctoa(buf); //上面临时变量已经完成使命,可以赋新值了

outfile.write((char *)&temp,sizeof(unsigned char)); //转成二进制写入

clength++; //统计代码结尾偏移加1,用于找到叶子结点位置

strcpy(buf,buf+8); //字符串前移八位

} //当此循环结束时,表示buf[]中已经小于8了,没到文件末尾,读下一个,继续,否则退出} //while 此层循环退出时,表示已到末尾,再判断buf中是否写完,没写完,连满至少8个字符,再写一个字节,就够了

if(strlen(buf)>0)

{

strcat(buf,"0000000");

temp=ctoa(buf); //前八位转成二进制形式

outfile.write((char *)&temp,sizeof(unsigned char));

clength++; //统计代码结尾偏移加1,用于找到叶子结点位置

}

outfile.seekp(4);

outfile.write((char *)&clength,sizeof(long)); //写入文件中将记录叶子结点位置

infile.close();

/*************************************将字符编码对照表写入文件****************************************/

long bytelen; //记录编码以二进制存储时需要占多少个字节

outfile.clear();

outfile.seekp(clength); //将文件指针移到编码后面的第一位置,在此处记录叶子结点数outfile.write((char *)&leafnum,sizeof(long)); //写入叶子结点数

for(i=0;i

{

outfile.write((char *)&header[i].b,sizeof(unsigned char)); //写入字符

header[i].count=strlen(header[i].bits); //不再设置其他变量,权值这时已无使用价值,可以用相应结点的权值变量记录长度

outfile.write((char *)&header[i].count,sizeof(unsigned char)); //写入长度的ASCII码

if(header[i].count%8==0)

bytelen=header[i].count/8;

else

{

bytelen=header[i].count/8+1;

strcat(header[i].bits,"0000000"); //在编码后面补0,使其最后凑满8的倍数,

//超过无妨,可以用bytelen控制好写入字节的长度

}

for(int j=0;j

{

temp=ctoa(header[i].bits);

outfile.write((char *)&temp,sizeof(unsigned char));

strcpy(header[i].bits,header[i].bits+8);

cout<<"该文件的哈夫曼的编码为:"<

for(i=0;i

{

cout<

}

}

} //此循环结束后就完成了编码对照表的写入

}//compress

void ctoa(unsigned char a,char code[]) /*字符转为二进制形式存入8位数组*/

{

int n=9;

for(int i=0;i

code[n-1]='\0'; //添加结束标志

n=n-2;

int c=(int)a;

while(c>0)

{

code[n--]=c%2+'0';

c=c/2;

}

}

int strcmp1(char buf[],struct head head[],int n,unsigned char &c) //将buf字符串与header[i].bits[]中匹配,成功后对应的字符由c带回

{

for(int i=0;i

if(strcmp(buf,head[i].bits)==0)

{

c=head[i].b;

return 1;

}

return 0;

}

void strcpy1(char buf[],char a[],int j) //将字符串a中长度为j的部分复制到buf数组中

{

for(int i=0;i

buf[i]=a[i];

buf[i]='\0';

}

void uncompress(char *infilename,char *outfilename)

{

long flength; //定义原文件长度,从压缩后文件前四字节获取值

long clength; //获取编码长度后的第一偏移量,从压缩文件第五字节开始获取值

int n; //叶子结点数,从编码尾端开始获取

string str; //读取编码到字符串,好进行统一解码

char code[9]; //将字符转为二进制数组形式暂存

unsigned char temp; //读取字符存放此临时变量

long readlen=0; //记录已经读取的长度(读文件解码时用)

long writelen=0; //记录已经写入的字节

long clen; //临时变量,读取字符编码对照表时使用

/************************************读入必要的数据*****************************************************/

void ctoa(unsigned char a,char code[]); //需要调用的函数的声明

ifstream infile(infilename,ios::binary);

if(!infile)

{

cerr<<"文件打开失败"<

return;

}

infile.read((char *)&flength,sizeof(long)); //读入原始文件长度,用于解码时判断

infile.read((char *)&clength,sizeof(long)); //读入叶子结点起始位置

infile.seekg(clength);

infile.read((char *)&n,sizeof(int)); //读入叶子结点数

/************************************读入编码对照表,放入header[i].bits[]数组中**************************/

infile.seekg(clength+4); //文件指针定位到字符编码对照表的起始

for(int i=0;i

{

infile.read((char *)&header[i].b,sizeof(unsigned char)); //读入字符

infile.read((char *)&header[i].count,sizeof(unsigned char)); //读入编码长度

clen=(int)header[i].count;

int diff=clen%8;

if(0==clen%8) //计算需要读取多少个字节

clen=clen/8;

else

clen=clen/8+1;

header[i].bits[0]='\0'; //初始化,方便后面进行连接

for(int j=0;j

{

infile.read((char *)&temp,1);

ctoa(temp,code);

strcat(header[i].bits,code); //将转换过来的编码进行连接

}

int bitlen=strlen(header[i].bits);

if(0!=diff)

header[i].bits[bitlen-8+diff]='\0';

}//for(int i=0;i

/************************************对读入的编码对照表进行排序,长度短的排在前面***********************/

for(i=0;i

{

for(int j=0;j

{

if(header[j].count>header[j+1].count)

{

tmp=header[j];

header[j]=header[j+1];

header[j+1]=tmp;

}

}

}

/************************************将编码读入内容,进行解码工作************************************/

readlen=0;

writelen=0;

ofstream outfile(outfilename,ios::binary|ios::out); //打开编码后文件

if(!outfile)

{

cerr<<"输出文件打开失败"<

return;

}

char buf[513]="\0"; //读入编码缓冲区

char buf1[257]="\0";

infile.seekg(8); /* 读取编码,解压连入缓冲区*/

while(1)

{

while(readlen<(clength-8)&&strlen(buf)<=256) //读满缓冲区

{

infile.read((char *)&temp,sizeof(temp));

ctoa(temp,code); //将字节转为数组

strcat(buf,code);

readlen++;

}//while

while(strlen(buf)>=256) //处理缓冲区,直到少于256位,再读满它

{

for(i=0;i

{

strcpy1(buf1,buf,i+1); //逐渐增多取,放入buf1,进行匹配

if(strcmp1(buf1,header,n,temp)==1)

{

outfile.write((char *)&temp,sizeof(unsigned char));

writelen++;

strcpy(buf,buf+i+1); //缓冲区前移

break;

}

}//for

if(writelen>=flength) break; //如果写入达到原文件长度,退出

}//while

if(readlen>=(clength-8)/*编码长度*/||writelen>=flength) break; //如果写入或者读入编码完毕,退出}//退出此循环后,还有未解码完成的buf[]

//对buf[]缓冲的善后处理

while(writelen

{

for(i=0;i

{

strcpy1(buf1,buf,i+1);

if(strcmp1(buf1,header,n,temp)==1)

{

outfile.write((char *)&temp,sizeof(unsigned char));

writelen++;

strcpy(buf,buf+i+1);

break;

}

}//for

}

infile.close(); //关闭文件

outfile.close();

}//uncompress()

void MainMeun()

{

cout<<"******************哈夫曼编码/译码器********************"<

cout<

cout<<"*********************Q----Quit*************************"<

cout<<"*********************H----Help*************************"<

cout<<"*********************C----Coding***********************"<

cout<<"*********************D----Decoding*********************"<

cout<<"*********************L----List Text Document***********"<

}

void show()

{

string contents;

char filename[200];

//cout<<"sfd";

cout<<"该文件的内容为:"<

cin>>filename;

ifstream in(filename,ios::out);

while(!in.eof())

in>>contents;

cout<

}

void help()

{

cout<

图像压缩编码方法

图像压缩编码方法综述 概述: 近年来, 随着数字化信息时代的到来和多媒体计算机技术的发展, 使得人 们所面对的各种数据量剧增, 数据压缩技术的研究受到人们越来越多的重视。 图像压缩编码就是在满足一定保真度和图像质量的前提下,对图像数据进行变换、编码和压缩,去除多余的数据以减少表示数字图像时需要的数据量,便于 图像的存储和传输。即以较少的数据量有损或无损地表示原来的像素矩阵的技术,也称图像编码。 图像压缩编码原理: 图像数据的压缩机理来自两个方面:一是利用图像中存在大量冗余度可供压缩;二是利用人眼的视觉特性。 图像数据的冗余度又可以分为空间冗余、时间冗余、结构冗余、知识冗余 和视觉冗余几个方面。 空间冗余:在一幅图像中规则的物体和规则的背景具有很强的相关性。 时间冗余:电视图像序列中相邻两幅图像之间有较大的相关性。 结构冗余和知识冗余:图像从大面积上看常存在有纹理结构,称之为结构 冗余。 视觉冗余:人眼的视觉系统对于图像的感知是非均匀和非线性的,对图像 的变化并不都能察觉出来。 人眼的视觉特性: 亮度辨别阈值:当景物的亮度在背景亮度基础上增加很少时,人眼是辨别 不出的,只有当亮度增加到某一数值时,人眼才能感觉其亮度有变化。人眼刚 刚能察觉的亮度变化值称为亮度辨别阈值。 视觉阈值:视觉阈值是指干扰或失真刚好可以被察觉的门限值,低于它就 察觉不出来,高于它才看得出来,这是一个统计值。 空间分辨力:空间分辨力是指对一幅图像相邻像素的灰度和细节的分辨力,视觉对于不同图像内容的分辨力不同。 掩盖效应:“掩盖效应”是指人眼对图像中量化误差的敏感程度,与图像 信号变化的剧烈程度有关。 图像压缩编码的分类: 根据编码过程中是否存在信息损耗可将图像编码分为: 无损压缩:又称为可逆编码(Reversible Coding),解压缩时可完全回复原始数据而不引起任何失真; 有损压缩:又称不可逆压缩(Non-Reversible Coding),不能完全恢复原始数据,一定的失真换来可观的压缩比。 根据编码原理可以将图像编码分为: 熵编码:熵编码是编码过程中按熵原理不丢失任何信息的编码。熵编码基

哈夫曼编码程序设计

算法与数据结构课程设计哈夫曼编码/译码器设计 学生姓名: 学号: 专业:(计算机科学与技术) 年级:(大二) 指导教师:(汪洋) 2009年6月19日 哈夫曼编码/译码器

问题描述: 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本,但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道)每端都需要一个完整的编/译码系统。试为这样的信息收发站写一哈夫曼编/译码系统。 基本要求: I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。 E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。 P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。 T:打印哈夫曼树(Tree printing)。将已在中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。 大体解题思路: (1)对输入的一段欲编码的字符串进行统计各个字符出现的次数,并它们转化为权值{w1,w2,……,wN}构成n棵二叉树的集合F={T1,T2,……,Tn}把它们保存到结构体数组HT[n]中,其中{Ti是按它们的ASCⅡ码值先后排序。其中每棵二叉树Ti中只有一个带权为Wi的根结点的权值为其左、右子树上根结点的权值之和。 (2)在HT[1..i]中选取两棵根结点的权值最小且没有被选过的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为左、右子树上根结点的权值之和。 (3)哈夫曼树已经建立后,从叶子到根逆向求每一个字符的哈夫曼编码。 概要设计: 实现的功能:1.查看原文(showpassage()),2.字符统计(showdetail()),

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

实验报告 实验课名称:数据结构实验 实验名称:文件压缩问题 班级:20132012 学号:姓名:时间:2015-6-9 一、问题描述 哈夫曼编码是一种常用的数据压缩技术,对数据文件进行哈夫曼编码可大大缩短文件的传输长度,提高信道利用率及传输效率。要求采用哈夫曼编码原理,统计文本文件中字符出现的词频,以词频作为权值,对文件进行哈夫曼编码以达到压缩文件的目的,再用哈夫曼编码进行译码解压缩。 二、数据结构设计 首先定义一个结构体: struct head { unsigned char b; //记录字符 long count; //权重 int parent,lch,rch; //定义双亲,左孩子,右孩子 char bits[256]; //存放哈夫曼编码的数组 } header[512],tmp; //头部一要定设置至少512个,因为结 点最多可达256,所有结点数最多可 达511 三、算法设计 输入要压缩的文件读文件并计算字符频率根据字符的频率,利用Huffman 编码思想创建Huffman树由创建的Huffman树来决定字符对应的编码,进行文件的压缩解码压缩即根据Huffman树进行译码 设计流程图如图1.1所示。

图1.1 设计流程图 (1)压缩文件 输入一个待压缩的文本文件名称(可带路径)如:D:\lu\lu.txt 统计文本文件中各字符的个数作为权值,生成哈夫曼树;将文本文件利用哈夫曼树进行编码,生成压缩文件。压缩文件名称=文本文件名.COD 如:D:\lu\lu.COD 压缩文件内容=哈夫曼树的核心内容+编码序列 for(int i=0;i<256;i++) { header[i].count=0; //初始化权重 header[i].b=(unsigned char)i; //初始化字符 } ifstream infile(infilename,ios::in|ios::binary); while(infile.peek()!=EOF) { infile.read((char *)&temp,sizeof(unsigned char)); //读入一个字符 header[temp].count++; //统计对应结点字符权重 flength++; //统计文件长度 } infile.close(); //关闭文件 for(i=0;i<256-1;i++) //对结点进行冒泡排序,权重大的放在上面,编码时效率高 for(int j=0;j<256-1-i;j++) if(header[j].count

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

┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊ 目录 目录 (1) 1 课程设计的目的和意义 (2) 2 需求分析 (3) 3 系统设计 (4) (1)设计思路及方案 (4) (2)模块的设计及介绍 (4) (3)主要模块程序流程图 (6) 4 系统实现 (10) (1)主调函数 (10) (2)建立HuffmanTree (10) (3)生成Huffman编码并写入文件 (13) (4)电文译码 (14) 5 系统调试 (16) 小结 (18) 参考文献 (19) 附录源程序 (20)

┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊ 1 课程设计的目的和意义 在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。 哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。 通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。 作为软件工程专业的学生,我们应该很好的掌握这门技术。在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。 在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。 在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见。同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。 数据结构课程具有比较强的理论性,同时也具有较强的可应用性和实践性。课程设计是一个重要的教学环节。我们在一般情况下都能够重视实验环节,但是容易忽略实验的总结,忽略实验报告的撰写。通过这次实验让我们明白:作为一名大学生必须严格训练分析总结能力、书面表达能力。需要逐步培养书写科学实验报告以及科技论文的能力。只有这样,我们的综合素质才会有好的提高。

哈夫曼编码译码问题

《数据结构》课程设计报告题目——哈夫曼编码译码问题 班级: 学号: 姓名: 时间:

一、设计目的与内容 1.设计目的 熟悉对哈夫曼编码的应用以及构造方法,熟悉对树的存储方式的应用。 2.设计内容: 任务:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本,但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一哈夫曼编/译码系统。 要求: 1)初始化:从终端输入字符集的大小n,以及n个字符和n个权值,建立哈夫曼树。 2)输出哈夫曼树,及各字符对应的编码。 3)编码:利用建好的哈夫曼树,对输入的待发送电文进行编码。同时输入原文及编码串。4)译码:利用建好的哈夫曼树,对输入的已接收电文进行译码。同时输入编码串及原文。 二、算法的基本思想 算法的主要思路是: (1)定义结构体存储赫夫曼树的结点类型 (2)定义函数strcpy(char *S1,char *S2)将字符串S2复制到S1 (3)定义函数Select(HuffmanTree HT,int t,int &s1,int &s2)在HT[1]到HT[t-1]中找出权值最小的两个S1和S2 (4)定义函数HuffmanCoding( HuffmanTree &HT,HuffmanCode &HC,int *w,int n)根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中 (5)定义函数InitHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch[],int &n )初始化赫夫曼数,要求用户输入字符和相应权值 (6)定义函数Encoding(HuffmanTree &HT, HuffmanCode &HC, char ch[])根据赫夫曼编码将用户指定的文件中的字符编成相应的编码,并将所得编码存储到用户指定文件 (7)定义函数Decoding(HuffmanTree HT, char ch[] , int n)对指定的存储由赫夫曼编码表示的信息的文件进行译码,翻译成相应的字符表示,并存储到指定文件 (8)定义函数ReadHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch[], int &n)从文件读取赫夫曼树 (9)定义主函数main()实现相应的功能 三、测试数据 首先运行程序: 请输入你要选择的功能 1.初始化 2.编码 3.译码 4.退出 1

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

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

《数据结构与算法》课程设计 目录 一、前言 1.摘要 2.《数据结构与算法》课程设计任务书 二、实验目的 三、题目--赫夫曼编码/译码器 1.问题描述 2.基本要求 3.测试要求 4.实现提示 四、需求分析--具体要求 五、概要设计 六、程序说明 七、详细设计 八、实验心得与体会

前言 1.摘要 随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。 算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。 《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。 学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。

北邮数据结构实验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 编码表节点结构:

数据结构哈夫曼编码译码器课程设计报告(有源程序)

JAVA语言实验报告 学院计算机工程学院班级计算1013 姓名 xxxx 学号 201081xxxx 成绩指导老师 xxxx 2012年09月03日

目录 目录 (1) 1 课程设计的目的和意义 (2) 2 需求分析 (3) 3 系统(项目)设计 (5) ①设计思路及方案 (5) ②模块的设计及介绍 (5) ③主要模块程序流程图 (8) 4 系统实现 (11) ①主调函数 (12) ②建立HuffmanTree (12) ③生成Huffman编码并写入文件 (15) ④电文译码 (16) 5 系统调试 (17) 参考文献 (21) 附录源程序 (22)

1 课程设计的目的和意义 在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。 哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。 通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。 作为信息管理专业的学生,我们应该很好的掌握这门技术。在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。 在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。 在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见。同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。 数据结构课程具有比较强的理论性,同时也具有较强的可应用性和实践性。课程设计是一个重要的教学环节。我们在一般情况下都能够重视实验环节,但是容易忽略实验的总结,忽略实验报告的撰写。通过这次实验让我们明白:作为一名大学生必须严格训练分析总结能力、书面表达能力。需要逐步培养书写科学实验报告以及科技论文的能力。只有这样,我们的综合素质才会有好的提高。

哈夫曼编码资料

哈夫曼编码译码系统 一、需求分析 1、程序的基本功能: ①构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n个字符以及n个对应的权 值,建立哈夫曼树;利用已将建好的哈弗曼树求每个叶结点的哈夫曼编码,并保存。 ②编码:利用已构造的哈弗曼编码对“明文”文件中的正文进行编码,然后将结果存 入“密文”文件中。 ③译码:将“密文”文件中的0、1代码序列进行译码。 ④打印“密文”文件:将文件以紧凑格式显示在终端上,同时,将此字符形式的编码 保存。 ⑤打印哈夫曼树:将已在内存中的哈夫曼以凹入表形式显示在终端上。 2、输入输出要求: ①从键盘接收字符集大小n、以及n个字符和n个权值; ②构造哈夫曼树:将HFMTree数组中的各个位置的各个域都添上相关的值,并将结构 体数组存入文件HTree.txt中。 ③打印哈夫曼树:从HFMTree数组读取相关的结点信息,以凹入表方式将各个结点画 出来; ④构造哈夫曼编码:先从文件HTree.txt中读入相关的字符信息进行哈夫曼编码,将字 符与其对应的编码存入文件HNode.txt中; ⑤编码:利用已构造的哈夫曼树对文件进行编码,打印结果,并将结果存入新建文件 中; ⑥译码:将密文文件中的内容利用HNode.txt中建立的编码规则进行翻译,打印结果, 并将结果存入新建文件中。 3、测试数据: 输入叶子结点个数为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。 二、概要设计 1、抽象数据类型的定义: ①采用静态链表作为哈夫曼树的存储结构; ②求哈夫曼编码时使用一维数组HCode作为哈夫曼编码信息的存储。 2、主模块的流程及各子模块的主要功能: ①int main() { 主菜单; swich语句结构选择; return 0; } ②in_park() { 输入车牌号; 若停车场已满,停入便道中,否则停入停车场; } ③output()

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

《数据结构与算法》课程设计(2009/2010学年第二学期第20周) 指导教师:王老师 班级:计算机科学与技术(3)班 学号: 姓名:

《数据结构与算法》课程设计 目录 一、前言 1.摘要 2.《数据结构与算法》课程设计任务书 二、实验目的 三、题目--赫夫曼编码/译码器 1.问题描述 2.基本要求 3.测试要求 4.实现提示 四、需求分析--具体要求 五、概要设计 六、程序说明 七、详细设计 八、实验心得与体会

前言 1.摘要 随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。 算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。 《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。 学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。 2.《数据结构与算法》课程设计任务书 《数据结构与算法》是计算机专业重要的核心课程之一,在计算机专业的学习过程中占有非常重要的地位。《数据结构与算法课程设计》就是要运用本课程以及到目前为止的有关课程中的知识和技术来解决实际问题。特别是面临非数值计算类型的应用问题时,需要选择适当的数据结构,设计出满足一定时间和空间限制的有效算法。 本课程设计要求同学独立完成一个较为完整的应用需求分析。并在设计和编写具有一定规模程序的过程中,深化对《数据结构与算法》课程中基本概念、理论和方法的理解;训练综合运用所学知识处理实际问题的能力,强化面向对象的程序设计理念;使自己的程序设计与调试水平有一个明显的提高。

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

实验三树的应用 一.实验题目: 树的应用——哈夫曼编码 二.实验内容: 利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。 要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。 三、程序源代码: #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;

基于哈夫曼编码的图像编解码系统设计及实现

课程设计任务书 题目:基于哈夫曼编码的图像编解码系统设计及实现 初始条件: 计算机 Windows8操作系统 MATLAB7.8.0软件 要求完成的主要任务: 设计哈夫曼编码的图像编解码系统、利用软件编写程序、仿真实现 时间安排: 第1-18周:理论讲解 第19周:理论设计,实验室安装调试以及撰写设计报告 答辩: 时间:7月2日 地点: 鉴主15楼通信实验室四 指导教师签名:年月日 系主任(或责任教师)签名:年月日

目录 目录........................................................................................................................ I矚慫润厲钐瘗睞枥庑赖。摘要....................................................................................................................... I I聞創沟燴鐺險爱氇谴净。ABSTRACT ......................................................................................................... I II残骛楼諍锩瀨濟溆塹籟。1引言..................................................................................................................... 1酽锕极額閉镇桧猪訣锥。 1.1图像数据压缩的目的.............................................................................. 1彈贸摄尔霁毙攬砖卤庑。 1.2图像数据压缩的原理.............................................................................. 1謀荞抟箧飆鐸怼类蒋薔。 1.3常用的压缩编码方法.............................................................................. 3厦礴恳蹒骈時盡继價骚。2哈夫曼编码......................................................................................................... 3茕桢广鳓鯡选块网羈泪。 2.1 哈夫曼编码简介..................................................................................... 3鹅娅尽損鹌惨歷茏鴛賴。 2.2哈夫曼编码步骤...................................................................................... 3籟丛妈羥为贍偾蛏练淨。 2.3 哈夫曼编码的缺点................................................................................. 5預頌圣鉉儐歲龈讶骅籴。3基于哈夫曼编码的图像编解码系统的程序设计............................................. 6渗釤呛俨匀谔鱉调硯錦。 3.1 分块程序设计分析................................................................................. 6铙誅卧泻噦圣骋贶頂廡。 3.2主程序...................................................................................................... 8擁締凤袜备訊顎轮烂蔷。 3.3程序函数.................................................................................................. 9贓熱俣阃歲匱阊邺镓騷。 3.3.1编码函数....................................................................................... 9坛摶乡囂忏蒌鍥铃氈淚。 3.3.2解码函数..................................................................................... 12蜡變黲癟報伥铉锚鈰赘。 3.3.3符号概率计算函数..................................................................... 14買鲷鴯譖昙膚遙闫撷凄。 3.3.4节点添加函数............................................................................. 14綾镝鯛駕櫬鹕踪韦辚糴。 3.3.5解码返回符号函数..................................................................... 15驅踬髏彦浃绥譎饴憂锦。4系统仿真结果................................................................................................... 15猫虿驢绘燈鮒诛髅貺庑。 4.1程序运行结果........................................................................................ 15锹籁饗迳琐筆襖鸥娅薔。 4.2 程序运行结果分析............................................................................... 17構氽頑黉碩饨荠龈话骛。 5.总结................................................................................................................... 18輒峄陽檉簖疖網儂號泶。参考文献.............................................................................................................. 19尧侧閆繭絳闕绚勵蜆贅。

哈夫曼编码课程设计报告

哈夫曼编码课程设计报 告 Last revised by LE LE in 2021

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

1 课程设计的目的和意义 在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。 哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。 通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。 2.需求分析 课题:哈夫曼编码译码器系统 问题描述:打开一篇英文文章,统计该文章中每个字符出现的次数,然后以它们作为权值,对每一个字符进行编码,编码完成后再对其编码进行译码。 问题补充:1. 从硬盘的一个文件里读出一段英语文章; 2. 统计这篇文章中的每个字符出现的次数; 3. 以字符出现字数作为权值,构建哈夫曼树 4. 对每个字符进行编码并将所编码写入文件然后对所编码进行破译。 具体介绍:在本课题中,我们在硬盘D盘中预先建立一个文档,在里面编辑一篇文章(大写)。然后运行程序,调用fileopen()函数读出该文章,显示在界面;再调用tongji()函数对 该文章的字符种类进行统计,并对每个字符的出现次数进行统计,并且在界面上显 示;然后以每个字符出现次数作为权值,调用Create_huffmanTree()函数构建哈夫曼 树。然后调用Huffman_bianma()函数对哈夫曼树进行编码,调用coding()函数将编码 写入文件。

哈夫曼编码

《数据结构》实验报告4 年级2012级学号201202024061 姓名王冠文成绩 专业计算机科学与技术实验地点电教楼303 指导教师杨丽 实验日期月日 实验项目哈夫曼编码 一、实验目的 根据最优二叉树构造哈夫曼编码利用哈夫曼树很容易求出给定字符集及其概率分布的最优前缀码。哈夫曼编码正是一种应用非常广泛,本次试验通过设计一个算法,体会和掌握哈夫曼编码要点。 二、实验问题描述 已知每一个字符出现的频率,构造哈夫曼树,并设计哈夫曼编码。 三、实验步骤 1、实验问题分 给定字符集的哈夫曼树生成后,求哈夫曼编码的具体实现过程是:依次以叶子T[i]为出发点,向上回溯至根为止。上溯时走左分支则生成代码0,走右分支则生成代码。 2、构思算法 3、功能函数设计 4、编写程序并运行调试 四、实验结果(程序)及分析 #include #include #include #include #define MAX_CHAR_KINDS 128 #define MAX_NUM 1000 typedef struct TreeNode { int weight; char data; char bin; struct TreeNode *parent; struct TreeNode *lChild, *rChild; } TreeNode; typedef struct { char data; char code[MAX_CHAR_KINDS]; } Code; void InverseStr(char *str) {

栅格数据存储压缩编码方法

栅格数据存储压缩编码方法 栅格数据存储压缩编码方法主要有:(1).链式编码(2).行程编码(3).块式编码(4).四叉树编码 (1).链式编码:由某一原点开始并按某些基本方向确定的单位矢量链。基本方向可定义为:东=0,南=3,西=2,北=1等,还应确定某一点为原点。(2).行程编码:只在各行(或列)数据的代码发生变化时依次记录该代码以及相同代码重复的个数,即按(属性值,重复个数)编码 (3).块式编码:块式编码是将行程编码扩大到二维的情况,把多边形范围划分成由像元组成的正方形,然后对各个正方形进行编码。 (4).四叉树编码而块状结构则用四叉树来描述,将图像区域按四个大小相同的象限四等分,每个象限又可根据一定规则判断是否继续等分为次一层的四个象限,无论分割到哪一层象限,只要子象限上仅含一种属性代码或符合既定要求的少数几种属性时,则停止继续分割。否则就一直分割到单个像元为止。而块状结构则用四叉树来描述。按照象限递归分割的原则所分图像区域的栅格阵列应为 2n×2n(n为分割的层数)的形式。下面就着重介绍四叉树编码。 四叉树编码又称为四分树、四元树编码。它是一种更有效地压编数据的方法。它将2n×2n像元阵列的区域,逐步分解为包含单一类型的方形区域,最小的方形区域为一个栅格像元。图像区域划分的原则是将区域分为大小相同的象限,而每一个象限又可根据一定规则判断是否继续等分为次一层的四个象限。其终止判据是,不管是哪一层上的象限,只要划分到仅代表一种地物或符合既定要求的几种地物时,则不再继续划分否则一直分到单个栅格像元为止。 所谓四叉树结构,即把整个2n×2n像元组成的阵列当作树的根结点,n 为极限分割次数,n+1为四分树的最大高度或最大层数。每个结点有分别代表西北、东北、西南、东南四个象限的四个分支。四个分支中要么是树叶,要么是树叉。树叉、树叶用方框表示,它说明该四分之一范围全属多边形范围(黑色)或全不属多边形范围(空心四方块),因此不再划分这些分枝;树用圆圈表示,它说明该四分之一范围内,部分在多边形内,另一部分在多边形外,因而继续划分,直到变成树叶为止。 为了在计算机中既能以最小的冗余存储与图像对应的四叉树,又能方便地完成各种图形操作,专家们已提出多种编码方式。下面介绍美国马里兰大学地理信

哈夫曼编码译码系统课程设计实验报告(含源代码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) 1课程设计的目的和意义 (3) 2需求分析 (4) 3概要设计 (4) 4详细设计 (8) ¥ 5调试分析和测试结果 (11) 6总结 (12) 7致谢 (13) 8附录 (13) 参考文献 (20) .

| ; 1 课程设计目的与意义 在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。 哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。 通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。 作为计算机专业的学生,我们应该很好的掌握这门技术。在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。 ( 在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们

可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。 在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见。同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。 数据结构课程具有比较强的理论性,同时也具有较强的可应用性和实践性。课程设计是一个重要的教学环节。我们在一般情况下都能够重视实验环节,但是容易忽略实验的总结,忽略实验报告的撰写。通过这次实验让我们明白:作为一名大学生必须严格训练分析总结能力、书面表达能力。需要逐步培养书写科学实验报告以及科技论文的能力。只有这样,我们的综合素质才会有好的提高。 2 需求分析 课题:哈夫曼编码译码器 ) 问题描述:打开一篇英文文章,统计该文章中每个字符出现的次数,然后以它们作为权值,对每一个字符进行编码,编码完成后再对其编码进行译码。问题补充:1. 从硬盘的一个文件里读出一段英语文章; 2. 统计这篇文章中的每个字符出现的次数; 3. 以字符出现字数作为权值,构建哈夫曼树,并将哈夫曼树的存储 结构的初态和终态进行输出; 4. 对每个字符进行编码并将所编码写入文件然后对所编码进行破 译。 具体介绍:在本课题中,我们在硬盘中预先建立一个文档,在里面编辑一篇文章。然后运行程序,调用函数读出该文章,显示在界面;再调用函数对该文章的字符种类进行统计,并对每个字符的出现次数进行统计,并且在界面上显示;然后以每个字符出现次数作为权值,调用函数构建哈夫曼树;并调用函数将哈夫曼的存储结构的初态和终态进行输出。然后调用函数对哈夫曼树进行编码,调用函数将编码写入文件;再调用对编码进行译码,再输出至界面。至此,整个工作就完成了 3 概要设计。

相关文档
最新文档