Huffman二叉树实验报告数据结构C语言文档格式.docx
- 文档编号:22692915
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:14
- 大小:80.14KB
Huffman二叉树实验报告数据结构C语言文档格式.docx
《Huffman二叉树实验报告数据结构C语言文档格式.docx》由会员分享,可在线阅读,更多相关《Huffman二叉树实验报告数据结构C语言文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
假设每种字符在输入的字符串中出现的次数为
,其编码长度为
,字符串中只有n种字符,则字符串总长为(即二叉树上带权路径的长度):
WPL=
当输入字符串jiang_hai_qiang时,
即可建立Huffman树,如下面两表所示,
根据此表可以建立如右图①的Huffman
二叉树的结构图
例如n的频率为2,q的频率为1,
这两个结点的共同parent结点的频率为
2+1=3。
编码表:
编码频率:
编码长度:
j:
1110
1
4
g:
100
2
3
i:
110
_:
101
a:
00
h:
1111
n:
010
q:
011
表1
num
weight
parent
lchild
rchild
9
12
13
10
5
11
6
7
8
14
15
表2
由此可以算出WPL=2×
3+3×
(3+2+2+2+1)+4×
(1+1)=42。
三.变量说明
全局变量A[]是用来存储字符的权值的。
weight代表的是该结点的权值。
程序中有m=2*n-1,是为Huffman二叉树开辟2n-1个结点。
在主函数中,m是用来记录输入字符串的个数的;
n是用来记录有多少种字符的;
a[]则是完整地记录输入的字符串;
而b[]是记录输入字符串中的不同字符。
HT表示Huffman树;
而HC表示Huffman编码。
其中还要说明的一些C++语句:
如cout<
<
HC[j+1]<
"
\t"
,代表的是输出语句;
而cin>
>
a代表的输入语句;
outfile<
HT[i].parent<
则是代表写入文件的语句。
四.函数与思路说明
此程序有1个主函数和7个子函数。
其中子函数分别为Calculate(),Select(),ASCII1(),ASCII2(),HuffmanCoding(),SC_HuffmanCoding(),HuffmanDecoding()。
子函数Calculate()是用来计算权值的。
子函数Select()的作用是在HT[1,2,…i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2。
子函数ASCII1()和ASCII2()分别是用来写入ASCII1和ASCII2文件的,这两个文件中分别存储Huffman二叉树的结构表和Huffman编码表。
子函数HuffmanCoding()主要是为赫夫曼二叉树编码,构造赫夫曼二叉树HT,并求出n个字符的赫夫曼编码HC。
其中此函数本身调用了子函数Select()和子函数ASCII1()。
在这个程序中,此子函数HuffmanCoding()为最重要的子函数。
它不但分配了Huffman二叉树结点的空间,且记录好每个结点的内容。
它还从叶子到根逆向求每个字符的赫夫曼编码。
SC_HuffmanCoding()这个子函数是用来输出字符串的赫夫曼编码的。
而最后的HuffmanDecoding()这个子函数,则是对编码后的数据进行解码。
五.程序执行结果
请任意输入一组字符:
jiang_hai_qiang
Huffman二叉树的结构:
numweightparentlchildrchild
11900
231200
331300
421000
521100
621100
71900
811000
921217
1031348
1141456
1251429
13615310
149151112
151501314
Huffman各字符的编码如下:
编码表:
编码频度:
11101
1103
003
0102
1002
1012
11111
0111
输入的字符串的Huffman编码:
11101100001010010111110011010101111000010100
请输入一串编码:
所得译码为:
六.结论
由程序的运行结果和前面的讨论得知,运用Huffman树来编码解码是非常节约空间,减少复杂度的。
通过这次编程,可以让我们深入了解Huffman树,学会灵活运用Huffman树,也可以让我们深刻地认识到Huffman树的优点和作用。
七.编程中遇到的问题以及解决方法
在编程过程中,运用C语言不会读入ASCII文件,后来运用C++语言成功写入和读出文件。
刚刚开始编程是打算连空格也作为字符来存储在Huffman树节点中的,即在主函数中也定义了数组c[100],用gets(c)输入一串字符,再利用for语句把字符串分为一个一个字符存储在数组a[100]中的,可是这样子的运行结果会有乱码。
后来就直接用C++语句cin>
a来替换上述的语句了,虽然不能存储空格字符,但是只要不在中间输入空格,运行结果是正确的,此程序还是挺好的。
八.附录
#include<
stdio.h>
stdlib.h>
string>
conio.h>
iostream>
fstream>
usingnamespacestd;
intA[100];
typedefstruct
{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
voidCalculate(chara[],charb[],intm,intn,int*w)//计算权值
{
inti,j;
for(i=0;
i<
n;
i++)
for(j=0;
j<
m;
j++)
if(b[i]==a[j])
A[i+1]=w[i+1]++;
}
voidSelect(HuffmanTreeHT,intn,int&
s1,int&
s2)
HT[0].weight=100;
//输入权值一般不能超过次数
s1=0;
s2=0;
for(inti=1;
=n;
++i)
if(HT[i].parent==0)
{
if(HT[i].weight<
HT[s2].weight)
{
if(HT[s2].weight<
HT[s1].weight)s1=s2;
s2=i;
}
elseif(HT[i].weight<
HT[s1].weight) {s1=s2;
s2=i;
}
voidASCII1(HuffmanTreeHT,intm)
inti;
ofstreamoutfile("
ASCII1.txt"
);
//写入ASCII1文件
outfile<
numweightparentlchildrchild"
endl;
for(i=1;
=m;
{
outfile<
;
HT[i].weight<
HT[i].lchild<
HT[i].rchild<
}
voidASCII2(charb[],HuffmanCodeHC,intn)
ASCII2.txt"
//写入ASCII2文件
编码频度"
b[i-1]<
:
HC[i]<
A[i]+1<
//赫夫曼二叉树编码
//其中w存放n个字符的权值(均>
0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
voidHuffmanCoding(HuffmanTree&
HT,HuffmanCode&
HC,int*w,intn)
intm,i,s1,s2,start;
unsignedc,f;
HuffmanTreep;
char*cd;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(p=HT+1,i=1;
++i,++p)//前n个结点初始化
{
p->
weight=w[i];
parent=0;
lchild=0;
rchild=0;
}
for(;
++i,++p)//对从第n+1个顶点到第2n-1个顶点初始化
weight=0;
for(i=n+1;
++i)//构建赫夫曼树
Select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
ASCII1(HT,m);
printf("
\nHuffman二叉树的结构:
\n"
numweightparentlchildrchild\n"
printf("
%d\t"
i);
HT[i].weight);
HT[i].parent);
HT[i].lchild);
%d\n"
HT[i].rchild);
//---从叶子到根逆向求每个字符的赫夫曼编码---
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char));
//分配求编码的工作空间
cd[n-1]='
\0'
//编码结束符
i++)//逐个字符求赫夫曼编码
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]='
elsecd[--start]='
HC[i]=(char*)malloc((n-start)*sizeof(char));
//为第i个字符编码分配空间
strcpy(HC[i],&
cd[start]);
//从cd复制编码串到HC
free(cd);
//释放工作空间
voidSC_HuffmanCoding(chara[],charb[],intm,intn,HuffmanCodeHC)//输出huffman编码
if(a[i]==b[j])
cout<
voidHuffmanDecoding(intn,charb[],HuffmanTreeHT)//对编码的二进制串进行解码
intm=2*n-1;
inti=m;
charc;
\n请输入一串编码:
cin>
c;
\n所得译码为:
while((c=='
)||(c=='
))//判断是否是合法字符
if(c=='
)i=HT[i].lchild;
//继续向左查找
elsei=HT[i].rchild;
//继续向右查找
if(HT[i].lchild==0)//直到分支的末端
printf("
%c"
b[i-1]);
//输出对应的符号
i=m;
//重新开始查找下一个
cin>
voidmain()
HuffmanTreeHT;
HuffmanCodeHC;
chara[100],b[100];
inti=0,j=0,m=0,n=0,*w;
请任意输入一组字符:
a;
while(a[i]) {m++;
i++;
}//用m来记录a中字符串个数
i;
if((i<
m)&
&
(a[j]==a[i])) {i++;
j=-1;
if(i<
m) {b[n]=a[i];
n++;
w=(int*)malloc((n+1)*sizeof(int));
i++)w[i]=0;
Calculate(a,b,m,n,w);
HuffmanCoding(HT,HC,w,n);
ASCII2(b,HC,n);
\nHuffman各字符的编码如下:
\t编码频度:
i++)cout<
SC_HuffmanCoding(a,b,m,n,HC);
HuffmanDecoding(n,b,HT);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Huffman 二叉 实验 报告 数据结构 语言