数据结构课程设计哈夫曼树及编码.docx
- 文档编号:14933894
- 上传时间:2023-06-28
- 格式:DOCX
- 页数:25
- 大小:235.33KB
数据结构课程设计哈夫曼树及编码.docx
《数据结构课程设计哈夫曼树及编码.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计哈夫曼树及编码.docx(25页珍藏版)》请在冰点文库上搜索。
数据结构课程设计哈夫曼树及编码
数据结构课程设计-哈夫曼树及编码
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(str[i]=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 哈夫曼树 编码
![提示](https://static.bingdoc.com/images/bang_tan.gif)