huffman编码课程设计报告.docx
- 文档编号:24109606
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:33
- 大小:79.17KB
huffman编码课程设计报告.docx
《huffman编码课程设计报告.docx》由会员分享,可在线阅读,更多相关《huffman编码课程设计报告.docx(33页珍藏版)》请在冰豆网上搜索。
huffman编码课程设计报告
南京航空航天大学
《数据结构》
课程设计报告
Huffman编码系统
班级:
学号:
姓名:
目录
一、需求分析:
·······························1
二、程序的主要功能:
·························2
三、程序运行平台:
···························3
四、系统总框架图:
···························4
五、数据结构:
·······························5
六、算法及时间复杂度:
·······················6
七、测试用例:
······························7
八、存在的不足与对策及编程体会··············8
九、程序源代码······························9
需求分析:
程序功能:
1.对huffman.txt文件中的英文文章统计各个主要字符出现的个数,算出频率。
2.对huffman.txt文件中的英文文章打印出直观形象的赫夫曼树,进行赫夫曼编码。
3.把各个字符的码字和整篇文章的码字输出到屏幕和文件中。
4.对编码后的码字进行解码,或者自己输入合适的码字进行解码,解码出的英文输出到屏幕和文件里。
主菜单:
1.查看原文:
调用voidshowpassage()函数。
对文章内的字符进行统计处理,用a[]记录每个字符出现的次数,用b[]记录出现概率。
2.字符统计:
调用voidshowdetail()函数。
直接显示记录结果。
3.赫夫曼编码并输出内容:
调用voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,float*w,intn)。
构造Huffman树(数组存贮),并对其编码,并输出结果。
4.输出整篇文章的编码:
调用voidprintcode()。
在原文中逐个读取一个字符,并找到其相应的编码,把它写到指定文件。
5.求最小权值:
调用voidminweight()。
6.对编码进行解码:
调用voiddecode()。
从根节点开始,找到叶子节点即找到一个源码。
程序的主要功能:
1、Huffman编码(voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,float*w,intn))
a)先将每个字符的出现概率存在数组HT[1-n]的weight中,并将每个数组元素的rchild,lchild,parent都置为0。
b)每次对数组中的parent值为0的元素的weight值进行堆排序,取出两个最小的值相加加入HT[]中。
新加入的元素的weight值为两个weight值相加,parent值为0,lchild,rchild为选出来的两个最小值的数组序号,两个选出来的最小值的parent值为新存入的元素的数组序号。
重复操作,直至数组存满
c)HC为char**类型,HC[i]里存放着第i个字符串的首地址。
cd[]存放编码,最后一个元素存放字符串截止符‘\0’,采用倒序存储,从叶子节点往上寻找,若是lchild,则从后往前在cd[]内存入0。
若是rchild,则从后往前在cd[]内存入1。
直至找到根节点。
将cd[]中存储的字符串拷贝到HC[i]指向的数组中。
d)重复c),直至所有字符都存入HC[i]指向的数组中,即编码成功。
2、堆排序(函数1、voidHeapAdjust(SqList&L,ints,intm),函数2、voidselect(HuffmanTreet,inti,int&s1,int&s2))
a)函数2是在函数1的基础上实现的,函数1的功能是已知L.r[s..m]中记录
的关键字除L.r[s].key之外均满足堆的定义,调整L.r[s]的关键字,使L.r[s..m]成为一个小顶堆(对其中记录的关键字而言)。
函数2的功能是在HuffmanTree中的前i个元素中找出parent值为0且weight值最小的两个元素的下标,将他们存入s1,s2中。
b)函数2、voidselect(HuffmanTreet,inti,int&s1,int&s2)
首先将HuffmanTree中的前i个元素(parent值为0)的weight值存入线性表L的数组r[]中,并将对应的在HuffmanTree中的位置存储在其otherinfo中。
从非叶子节点开始堆排序,调用函数1,形成一个小顶堆。
取堆顶元素将其otherinfo等于s1,将小顶堆的首尾元素对调,对除最后一个元素以外的其他所有元素进行堆排序,形成小顶堆。
取堆顶元素将其otherinfo等于s2。
3、解码(voiddecode())
从根节点(即parent值为0的HuffmanTree数组中的最后一个元素)往下,为0则往左枝继续,为1则往右枝继续,直至叶子节点(即rchild,lchild都为0的HuffmanTree数组中的元素),如果未到叶子节点01字符串就终止了,即输出提示信息。
4、其他功能(如将编码,解码输入到文件中;从文件中读取相关内容;求最小权值等)
由于操作,原理简单,在此不一一赘述。
程序运行平台:
VC++6.0
具体如何操作,可以根据信息提示进行相关操作,比较简单,在这里不必做太多说明。
系统总框架图:
数据结构:
1、赫夫曼树结构体
typedefstruct
{
floatweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
2、堆结构体
typedefstruct
{
floatkey;//关键字项
intotherinfo;//其他数据项(此题目中用不到)
}RedType;
typedefstruct
{
RedTyper[MAXSIZE+1];//r[0]闲置用作哨兵
intlength;//顺序表长度
}SqList;
算法及时间复杂度(算法见源代码):
1、voiddecode():
//解码
时间复杂度:
O(n)//n个01字符
2、voidHeapAdjust(SqList&L,ints,intm)和voidselect(HuffmanTreet,inti,int&s1,int&s2)//堆排序
时间复杂度:
<=O(n*logn)
3、voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,float*w,intn)//Huffman编码
时间复杂度:
O(n)
测试用例:
1、Huffman.txt(待译文章)
内容:
Inthepastfouryears,AdventConspiracychurcheshavedonatedmillionsofdollarstodigwellsindevelopingcountriesthroughLivingWaterInternationalandotherorganizations.McKinleylikestopointoutthatafractionofthemoneyAmericansspendatretailersinthemonthofDecembercouldsupplytheentireworldwithcleanwater.IfmoreChristianschangedhowtheythoughtaboutgivingatChristmas,heargues,theholidaycouldbetransformativeinareligiousandpracticalsense.
2、bianma.txt(编码后的文章)
111111*********1111111000011110111110010010100001110011101100110000100001011110100111101101001010001010010111110100110100101011010111110011110011100001110001100100101101011010100110100111111001100110100001011001100111101000111100111010001010110111101101100001111010110011010110111110010110110000000010111000011100011111000011001111011011000000000001010010100011111100100011101101101100100111001011110100000000000111110110111111011011101001010110100001000100100101101110010011110011100001000011111000101101111010001111110000110101100001000001000011111000010110010101011011100100111001011101011001101010111110110111110011010101011110101100101110000111101000001111010011101101111100011000011110101011111000010100100101001111011011000111110101100101110000111000101100001111001011001101100010101101110000110101001111100001011011000101101000111111001000111100100100010110111110011110000100011001111100001110101100111101011101100101011010100111100101110000111111100001100111111000011110111110010110000111110101001111110101001011101010110111001110100111000111100011001001101011101101111101011001110101110111001010101100001101010100011111011011111111000011110111110010110000111110000111111000011001111011011101100111101100101010010011010101111100111000010000000011011110001010001001001001000000010011111110000111101111110101111100101101011101111001011100001010000011011110010111011110000111111001100001101101001111110010111010110011010101011000011110110110011111001011000010111011111001100110101101100011100101110100111000111110011001110100111001001101011011110011100000101111111000011110101001111111000011100001000001000011110011110100100100100001000110011100100101100101010110111001001111010110011110011001101011011000111001001011010000101001011110011110111110100101001000100011010001010010111111000011110111100111000000010110110110100100111111001110000100000000110111101001001101111110001011010011100010110011000010110010110101100101100101011011111011011111110101110101110100001011001001011100001000000111110100111011011111001000101101010011110010111001110100000111000111010111000111010110000011000110
3、jiema.txt(解码后的文章)
内容:
inthepastfouryears,adventconspiracychurcheshavedonatedmillionsofdollarstodigwellsindevelopingcountriesthroughlivingwaterinternationalandotherorganizations.mckinleylikestopointoutthatafractionofthemoneyamericansspendatretailersinthemonthofdecembercouldsupplytheentireworldwithcleanwater.ifmorechristianschangedhowtheythoughtaboutgivingatchristmas,heargues,theholidaycouldbetransformativeinareligiousandpracticalsense.
4、测试解码:
输入:
100101101010010010
输出:
map(不完整信息)
输入:
111001*********00010
输出:
hdl(不完整信息)
输入:
00010101000101010101000010010100001000
输出:
srsrrlmlo
存在的不足与对策及编程体会:
1、不足:
部分复杂的符号(如“”,‘’,!
,?
等)为进行编码,使得程序的通用性降低,并且大小写未进行区分,使得文章部分失真。
程序执行时必须先执行1,2,3。
不能自由选择,一旦未按指定执行,则会出现错误而无法继续,可能会导致死机。
2、编程体会:
学完数据结构,我对Huffman这个概念不是特别清楚,对其只有一个大概的印象。
通过这次的课程设计,我对Huffman编码有了一个更深刻的认识。
它不仅解码唯一,并且使得整个码长最短。
是一个高效实用的程序。
在编程的过程中,也遇到不少问题。
例如Huffman树的建立,筛选最小值等相关程序尽管在书上能找到完整的算法,但是要根据自己的程序做相应的修改就不是一件简单的事了。
程序中主要用的知识有赫夫曼算法,堆排序,字符串处理,二重指针,一重指针,结构体,文件,switch和循环控制等等,将诸多知识融合到一个程序中对我来说确实是个挑战。
之后我在主要功能的基础上又增加了不少附加功能,主要是为了让使用者更加直观的看出程序执行的结果,不仅在屏幕中能看到执行结果,在文本中也保存了相关结果。
心思够细腻吧,嘿嘿。
最后经过反复的修改,完备,终于做出了自己的Huffman编码,那份满足感充斥着整个人。
课程设计强化了我的基础知识,并且将知识实践化,使得自己对算法有了更深刻的理解。
程序源代码:
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"conio.h"
#include"iostream.h"
#defineMAXSIZE60
//********************************************************************************
//*************************定义赫夫曼树结构体*************************************
//********************************************************************************
typedefstruct
{
floatweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
//********************************************************************************
//***********************定义堆结构体*********************************************
//********************************************************************************
typedefstruct
{
floatkey;//关键字项
intotherinfo;//其他数据项(此题目中用不到)
}RedType;
typedefstruct
{
RedTyper[MAXSIZE+1];//r[0]闲置用作哨兵
intlength;//顺序表长度
}SqList;
//********************************************************************************//*************************全局变量***********************************************
//********************************************************************************
HuffmanTreeHT;//赫夫曼树
HuffmanCodeHC;//码值
FILE*fp,*fp1,*fp2;
inta[30]={0};
floatb[30];
float*w;//权
//********************************************************************************//**********测试解码(可以输入一个不正确的二进制码串),显示在屏幕上***************
//********************************************************************************
voidtestdecode()
{
charstr[200];//存放自己输入的码字
intp,p1,i;//解码的线索
charch;
printf("\n请根据以上各个字符的编码输入一串二进制码字(200个以内):
\n");
gets(str);
printf("解码后为:
\n");
p=59;//最初令p为树根整数,p由根顺着树枝一直到树叶
i=0;
ch=str[i++];
while(ch!
='\0')
{
for(;ch!
='\0'&&(HT[p].lchild!
=0||HT[p].rchild!
=0);)//未到叶子节点即为得到相应源码
{
if(ch=='0')
{
p=HT[p].lchild;
}
elseif(ch=='1')
{
p=HT[p].rchild;
}
else
{
printf("\n你输入了'0','1'之外的字符,无法正确译码,请检查!
\n");
return;//直接结束
}
ch=str[i++];//下一个码字不断的取下一个
}
if(p<=30)//小于等于30的时候才正确,有可能最后一位p还没有在1-30范围内的时候就没有二进制码了,也就是说二进制码最后不完整。
switch(p)
{
case27:
printf(",");
break;
case28:
printf(".");
break;
case29:
printf("");
break;
case30:
printf("\n");
break;
default:
printf("%c",p+96);//小写字母
}
p1=p;//让p1记住p,以便判断最后一位是否完整
p=59;//这里p要重置为59,因为经过上面的程序p已经变化了,不重置为1则HT[p].lchild!
=0||HT[p].rchild!
=0所以for语句无法进行!
!
!
!
}//while循环
if(p1>30)
printf("\n以上正确译出了前面的字符,由于你输入的二进制码不完整,最后一位字符无法译出,请检查!
\n");
}
//********************************************************************************
//**************下面是解码,写入文件中并在屏幕上显示******************************
//********************************************************************************
voiddecode()
{
intp;
charch;
printf("\n\n对编码解码后的如下:
\n");
fp1=fopen("bianma.txt","r");
if(!
fp1)
{
printf("cannotopenthisfile!
\n");
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- huffman 编码 课程设计 报告