数据结构课程设计哈夫曼树及编码.docx

上传人:b****4 文档编号:4800029 上传时间:2022-12-09 格式:DOCX 页数:22 大小:236.96KB
下载 相关 举报
数据结构课程设计哈夫曼树及编码.docx_第1页
第1页 / 共22页
数据结构课程设计哈夫曼树及编码.docx_第2页
第2页 / 共22页
数据结构课程设计哈夫曼树及编码.docx_第3页
第3页 / 共22页
数据结构课程设计哈夫曼树及编码.docx_第4页
第4页 / 共22页
数据结构课程设计哈夫曼树及编码.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

数据结构课程设计哈夫曼树及编码.docx

《数据结构课程设计哈夫曼树及编码.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计哈夫曼树及编码.docx(22页珍藏版)》请在冰豆网上搜索。

数据结构课程设计哈夫曼树及编码.docx

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

 

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

 

HUFFMAN树及编码

1.需求分析

随机输入一篇英文文章(或读一个TXT文件),生成并显示HUFFMAN树,输出每个字母的HUFFMAN编码,判断ASCII编码与HUFFMAN编码对本篇报文长度节省效果。

(a)输入的形式为键盘随机输入,输入的字符串长度在10000以内;

(b)输出HUFFMAN树的存储结构;

(c)程序功能为输入英文文章中每个字母的HUFFMAN编码,以及与ASCLL码编码长度的比较结果;

(d)测试数据:

正确的输入一篇英文文章,会输出各个字母的HUFFMAN编码。

错误的输入即其输出输入错误。

2.概要设计

首先统计英文文章中各个字母的个数作为权值,再统计出现的字母的个数,以决定所构造赫夫曼树的节点个数,之后便开始构造赫夫曼树,再构造每个节点的哈夫曼编码。

所设计的抽象数据类型如下:

typedefstruct

{

unsignedintweight;//权值

unsignedintparent,lchild,rchild;//双亲,左孩子,右孩子

}HTNode,*HuffmanTree;

typedefchar**HuffmanCode;

所设计的函数如下:

intmin(HuffmanTreeHT,inti)找出所有权值中最小的那个。

voidSelect(HuffmanTreeHT,inti,int&s1,int&s2)找出每次最小的两个权值最小的权值。

StatusHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn)

构造赫夫曼树并构造每个字母的赫夫曼编码。

voidPrintHT(HuffmanTreeHT,intn)

输出赫夫曼树的存储结构。

3.详细设计

intmin(HuffmanTreeHT,inti)

{intj,flag=1;

unsignedintk=10000;

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

{

if(HT[j].weight

{

k=HT[j].weight,flag=j;

}//if

}

HT[flag].parent=1;

returnflag;

}

voidSelect(HuffmanTreeHT,inti,int&s1,int&s2)

{

intj;

s1=min(HT,i);

s2=min(HT,i);

if(s1>s2)

{

j=s1;

s1=s2;

s2=j;

}

}

StatusHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn)

{

ints1,s2,i,start,f;

char*cd;

HuffmanTreep=NULL;//p是工作指针,指向赫夫曼树中的结点

if(n<=1)

{

returnERROR;

}

intm=2*n-1;//n个字符构造的赫夫曼树共有m=2*n-1个结点

printf("->待构造的赫夫曼树共有2×%d-1=%d个结点\n",n,m);

if(!

(HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode))))//申请赫夫曼树结点占用的内存空间,0号单元不用

{

exit(OVERFLOW);

}//if

printf("->赫夫曼树共分配了%d个结点空间,其中包含一个不用的0号单元\n",m+1);

//printf("->初始化所有叶子节点的权值,父亲和孩子:

\n");

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

{

p->weight=*w;

p->parent=0;//双亲初始值为0,表示此结点还没有被选择最小的算法选择过

p->lchild=0;//左右孩子初始化为0,表示空

p->rchild=0;

}

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

{

p->weight=0;

p->parent=0;

p->lchild=0;

p->rchild=0;

}

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

{

Select(HT,i-1,s1,s2);

HT[s1].parent=i;//选出的两个权值最小的结点的双亲就是即将生成的结点

HT[s2].parent=i;

HT[i].lchild=s1;//即将生成的结点左孩子是s1,右孩子是s2,

HT[i].rchild=s2;//因为s1比s2先选,因此s1总是小于等于s2

HT[i].weight=HT[s1].weight+HT[s2].weight;//即将生成结点的权值就是两个权值最小的结点的权值之和

}

if(!

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

{

exit(OVERFLOW);

}//if

if(!

(cd=(char*)malloc(n*sizeof(char))))

{

exit(OVERFLOW);

}

cd[n-1]='\0';

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

{

start=n-1;

for(intc=i,f=HT[i].parent;f!

=0;c=f,f=HT[f].parent)

{

if(HT[f].lchild==c)

{

cd[--start]='0';

}//if

else//叶子结点根结点的右孩子

{

cd[--start]='1';

}//else

}

if(!

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

{

exit(OVERFLOW);

}

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

//printf("->叶子节点%d的赫夫曼编码为:

%s\n",i,HC[i]);

}

free(cd);

returnOK;

}//HuffmanCoding

 

voidPrintHT(HuffmanTreeHT,intn)

{

intm=2*n-1;

printf("\n+-------------------------------------------------------------+\n");

printf("|赫夫曼树HT的存储结构|\n");

printf("+----------+----------+----------+--------------+-------------+\n");

printf("|结点编号|weight|parent|leftchild|rightchild|\n");

printf("+----------+----------+----------+--------------+-------------+\n");

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

{

printf("|%4d|%4d|%4d|%4d|%4d|\n",

i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

printf("+----------+----------+----------+--------------+-------------+\n");

}

}

for(inti=0;i

{

if(str[i]=='A')

a[65]++;

elseif(str[i]=='B')

a[66]++;

elseif(str[i]=='C')

a[67]++;

elseif(str[i]=='D')

a[68]++;

elseif(str[i]=='E')

a[69]++;

elseif(str[i]=='F')

a[70]++;

elseif(str[i]=='G')

a[71]++;

elseif(str[i]=='H')

a[72]++;

elseif(str[i]=='I')

a[73]++;

elseif(str[i]=='J')

a[74]++;

elseif(str[i]=='K')

a[75]++;

elseif(str[i]=='L')

a[76]++;

elseif(str[i]=='M')

a[77]++;

elseif(str[i]=='N')

a[78]++//部分统计字母代码

主程序首先随机输入一篇英文文章,再统计各字母个数,再调用HuffmanCoding(HT,HC,w,n)函数,此函数又会调用voidSelect(HuffmanTreeHT,inti,int&s1,int&s2)函数,而此函数又会调用intmin(HuffmanTreeHT,inti)函数,构造完成后便调用PrintHT(HT,n)函数输出赫夫曼树的存储结构。

 

调用

 

调用

 

调用

 

调用

输入界面:

 

输出界面:

 

 

4.调试分析

(a)调试过程中未设计多种不合理输入的对应输出结果,后加上。

(b)算法的时间复杂度为O(n3),StatusHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn)函数中的一重for循环调用了select函数,而select函数又调用了min函数,故共有三重for循环,故时间复杂度为O(n3)。

(c)经过这次课程设计,让我受益匪浅,使我掌握了二叉树的的存储结构和赫夫曼编码的基本思想。

程序中有多处运用了三重循环,这里很多地方能够优化以达到减小时间和空间复杂度。

在此次课程设计的最大收获就是让我明白一个道理:

无论你做的是多么小的一个程序或软件,都要使用模块化设计,这样使程序实现的功能更清晰明了。

5.用户使用说明

直接输入一篇英文文章即可。

6.测试结果

a.正确输入:

ThereisnodoubtthatInternethaschangedourlifegreatlyItmakestheworldsmallerPeoplecangettoknowtheworldinashorttimeandmakefriendsfromallovertheworldWhileontheotherhandthemuchattentionontheInternetisolatesthedistanceandreducesfacetofacecommunicationManyyearsagobeforethepopularityofcomputerpeoplegottoknowtheworldbylisteningtotheradioorreadingnewspaperButnowadayspeoplecanjustreadtheinstantnewsontheInternetandgetthefirsthandinformationimmediatelyThefastwaytomasterinformationmakesthemfeelkeepingintouchwiththeworldTheworldseemssoneartothem

结果:

b.错误的输入

7.测试情况:

测试情况如设计的一致,首先输出各字母及在文章出现的次数,再输出各字母的赫夫曼编码,最后输出ASCLL码与赫夫曼编码的差异。

附程序源代码:

#include

#include

#include

#defineOVERFLOW-2

#defineOK1

#defineERROR0

typedefintStatus;

typedefstruct

{

unsignedintweight;//权值

unsignedintparent,lchild,rchild;//双亲,左孩子,右孩子

}HTNode,*HuffmanTree;//动态分配数组存储赫夫曼树

typedefchar**HuffmanCode;//动态分配数组存储赫夫曼编码表

intmin(HuffmanTreeHT,inti)

{

intj,flag=1;

unsignedintk=10000;

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

{

if(HT[j].weight

{

k=HT[j].weight,flag=j;

}//if

}

HT[flag].parent=1;

returnflag;

}

voidSelect(HuffmanTreeHT,inti,int&s1,int&s2)

{

intj;

s1=min(HT,i);

s2=min(HT,i);

if(s1>s2)

{

j=s1;

s1=s2;

s2=j;

}

}

voidPrintHT(HuffmanTreeHT,intn)

{

intm=2*n-1;

printf("\n+-------------------------------------------------------------+\n");

printf("|赫夫曼树HT的存储结构|\n");

printf("+----------+----------+----------+--------------+-------------+\n");

printf("|结点编号|weight|parent|leftchild|rightchild|\n");

printf("+----------+----------+----------+--------------+-------------+\n");

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

{

printf("|%4d|%4d|%4d|%4d|%4d|\n",

i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

printf("+----------+----------+----------+--------------+-------------+\n");

}

}

StatusHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn)

{

ints1,s2,i,start,f;

char*cd;

HuffmanTreep=NULL;//p是工作指针,指向赫夫曼树中的结点

if(n<=1)

{

returnERROR;

}

intm=2*n-1;//n个字符构造的赫夫曼树共有m=2*n-1个结点

printf("->待构造的赫夫曼树共有2×%d-1=%d个结点\n",n,m);

if(!

(HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode))))//申请赫夫曼树结点占用的内存空间,0号单元不用

{

exit(OVERFLOW);

}//if

printf("->赫夫曼树共分配了%d个结点空间,其中包含一个不用的0号单元\n",m+1);

//printf("->初始化所有叶子节点的权值,父亲和孩子:

\n");

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

{

p->weight=*w;

p->parent=0;//双亲初始值为0,表示此结点还没有被选择最小的算法选择过

p->lchild=0;//左右孩子初始化为0,表示空

p->rchild=0;

}

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

{

p->weight=0;

p->parent=0;

p->lchild=0;

p->rchild=0;

}

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

{

Select(HT,i-1,s1,s2);

HT[s1].parent=i;//选出的两个权值最小的结点的双亲就是即将生成的结点

HT[s2].parent=i;

HT[i].lchild=s1;//即将生成的结点左孩子是s1,右孩子是s2,

HT[i].rchild=s2;//因为s1比s2先选,因此s1总是小于等于s2

HT[i].weight=HT[s1].weight+HT[s2].weight;//即将生成结点的权值就是两个权值最小的结点的权值之和

}

if(!

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

{

exit(OVERFLOW);

}//if

if(!

(cd=(char*)malloc(n*sizeof(char))))

{

exit(OVERFLOW);

}

cd[n-1]='\0';

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

{

start=n-1;

for(intc=i,f=HT[i].parent;f!

=0;c=f,f=HT[f].parent)

{

if(HT[f].lchild==c)

{

cd[--start]='0';

}//if

else//叶子结点根结点的右孩子

{

cd[--start]='1';

}//else

}

if(!

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

{

exit(OVERFLOW);

}

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

//printf("->叶子节点%d的赫夫曼编码为:

%s\n",i,HC[i]);

}

free(cd);

returnOK;

}//HuffmanCoding

intmain()

{

HuffmanTreeHT;

HuffmanCodeHC;

int*w;

charstr[10005];

inta[150],b[60];

memset(a,0,sizeof(int)*150);

printf("请随机输入英文文章:

");

scanf("%s",str);

intlen=strlen(str);

for(inti=0;i

{

if(str[i]=='A')

a[65]++;

elseif(str[i]=='B')

a[66]++;

elseif(str[i]=='C')

a[67]++;

elseif(str[i]=='D')

a[68]++;

elseif(str[i]=='E')

a[69]++;

elseif(str[i]=='F')

a[70]++;

elseif(str[i]=='G')

a[71]++;

elseif(str[i]=='H')

a[72]++;

elseif(str[i]=='I')

a[73]++;

elseif(str[i]=='J')

a[74]++;

elseif(str[i]=='K')

a[75]++;

elseif(str[i]=='L')

a[76]++;

elseif(str[i]=='M')

a[77]++;

elseif(str[i]=='N')

a[78]++;

elseif(str[i]=='O')

a[79]++;

elseif(str[i]=='P')

a[80]++;

elseif(str[i]=='Q')

a[81]++;

elseif(str[i]=='R')

a[82]++;

elseif(str[i]=='S')

a[83]++;

elseif(str[i]=='T')

a[84]++;

elseif(str[i]=='U')

a[85]++;

elseif(str[i]=='V')

a[86]++;

elseif(str[i]=='W')

a[87]++;

elseif(str[i]=='X')

a[88]++;

elseif(str[i]=='Y')

a[89]++;

elseif(str[i]=='Z')

a[90]++;

elseif(str[i]=='a')

a[97]++;

elseif(str[i]=='b')

a[98]++;

elseif(str[i]=='c')

a[99]++;

elseif(str[i]=='d')

a[100]++;

elseif(str[i]=='e')

a[101]++;

elseif(str[i]=='f')

a[102]++;

elseif(str[i]=='g')

a[103]++;

elseif(str[i]=='h')

a[104]++;

elseif(str[i]=='i')

a[105]++;

elseif(

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

当前位置:首页 > 求职职场 > 简历

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

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