数据结构实验 树和二叉树的应用文档格式.docx
《数据结构实验 树和二叉树的应用文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验 树和二叉树的应用文档格式.docx(9页珍藏版)》请在冰豆网上搜索。
4学时
●设计原理:
利用二叉树来设计二进制的前缀编码。
事先约定左分支表示字符‘0’,右分支表示字符‘1’,则可以根据根节点到叶子节点的路径上分支字符组成的字符串作为该叶子节点字符的编码。
假设每种字符出现的次数为w(i),其编码长度为l(i),只有n种字符则,文章的总长度为∑w(i)l(i)。
对应到二叉树上,置w(i)为叶子节点的权,l(i)为从根到叶子的路径长度。
则∑w(i)l(i)为二叉树上带权路径长度。
由此,设计文章总长最短的二进制前缀编码即为以n种字符出新的频率作权,由此得到的二进制前缀编码则为赫夫曼编码。
●详细程序清单及注释说明:
#include<
stdio.h>
stdlib.h>
malloc.h>
string.h>
iostream>
usingnamespacestd;
typedefchar**HaffmanCode;
typedefstruct
{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
voidSelect(HuffmanTree&
HT,inti,int&
s1,int&
s2)
intn,m=0;
for(n=1,m=0;
n<
=i&
&
m!
=2;
n++)
{
if(HT[n].parent==0)
if(m==0)
s1=n;
m=1;
continue;
}
if(m==1)
s2=n;
m=2;
break;
n++;
for(;
=i;
if(HT[n].weight<
HT[s1].weight)
if(HT[s1].weight<
HT[s2].weight)
s2=s1;
if(HT[s2].weight<
s1=s2;
}
voidHuffmanCoding(HuffmanTree&
HT,HaffmanCode&
HC,int*w,intn)
//w存放n个字符的权值(均>
0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
intm,i,s1,s2,start,c,f;
char*cd;
if(n<
=1)return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
//0号单元未用
for(i=1;
i<
=n;
++i)
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
=m;
HT[i].weight=0;
for(i=n;
m;
i++)
{//建立赫夫曼树
//在HT[1...i-1]选择parent为0且weight最小的两个节点,其序号分别为S1和S2
Select(HT,i,s1,s2);
HT[s1].parent=i+1;
HT[s2].parent=i+1;
HT[i+1].lchild=s1;
HT[i+1].rchild=s2;
HT[i+1].weight=HT[s1].weight+HT[s2].weight;
//---从叶子到根逆向求每个字符的赫夫曼编码---
HC=(HaffmanCode)malloc((n+1)*sizeof(char*));
//分配n个字符编码的头指针向量
cd=(char*)malloc(n*sizeof(char));
//分配求编码的工作区间
cd[n-1]='
\0'
;
//编码结束符
start=n-1;
for(c=i,f=HT[i].parent;
f!
=0;
c=f,f=HT[f].parent)//从叶子到干逆向求编码
if(HT[f].lchild==c)cd[--start]='
0'
elsecd[--start]='
1'
HC[i]=(char*)malloc((n-start)*sizeof(char));
//为第i个字符编码分配空间
strcpy(HC[i],&
cd[start]);
//从cd复制编码(串)到HC
free(cd);
//释放工作空间
intmain()
HuffmanTreeHT;
HaffmanCodeHC;
intn,i,j;
int*w;
printf("
请输入字符的个数:
\n"
);
scanf("
%d"
&
n);
w=(int*)malloc(n*sizeof(int));
for(i=0;
n;
{
请输入第%d个字符的权数:
"
i+1);
w[i]);
}
HuffmanCoding(HT,HC,w,n);
赫夫曼编码为:
%s\n"
HC[i]);
return0;
●运行测试结果:
给定字符数:
8
各字符权值:
5、29、7、8、14、23、3、11
构建完成后的赫夫曼树:
●实验中所遇的问题及解决方法:
.程序在最后编译时出现错误。
原因:
程序在刚开始编写的时候并没有给出此程序所需要的全部头文件,当程序引用系统自定义函数时,由于没有这些头文件,所以程序编译没有通过。
.程序在赋权值时出现错误,第一个权值并没有赋值给相对应的向量。
在循环函数设计时出现错误,循环函数在赋初值时没有考虑到程序未使用0号单元,所以当已被赋值的向量赋值给其他向量时,数组中的第一个数值被略过,导致程序结果出现错误。
.函数当中Select函数的设计
Select是构建赫夫曼树的的核心构建函数。
此函数的功能是为了区分给定字符中各种字符的权数的大小。
并将其按顺序排列,构建过程中,由于对算法的结构认识不清楚,导致在应该区分S1和S2时,程序并没有进行此项工作,造成了各个节点没有按预期的得到应有的顺序,程序执行异常。
通过设置辅助变量m区分S1和S2,区分后,通过循环结构将相应的权值赋给S1或S2。