实验三哈夫曼树编码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

华北水利水电学院数据结构实验报告
2010~2011学年第二学期2010 级计算机专业
班级:176 学号:201017602 姓名:勾志竟
一、实验题目:
(1)理解哈夫曼树的含义和性质。

(2)掌握哈夫曼树的存储结构以及描述方法。

(3)掌握哈夫曼树的生成方法。

(4)掌握哈夫曼编码的一般方法,并理解其在数据通讯中的应用。

二、实验内容:
哈夫曼树与哈弗曼编码、译码
问题描述:利用哈弗曼编码进行通信可以大大提高通信利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码。

三、程序源代码:
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef struct{
char c; //代码;
int w; //代码权值;
char code[MaxSize]; //代码的Huffman编码;
}HuffCode[MaxSize];
typedef struct{
int Weight; //权值;
int LChild,RChild,Parent;
}HTNode,HuffTree[MaxSize];
void HuffmanTree(HuffTree HT,int length,HuffCode hc); //生成Huffman树;
void SelectHTNode(HuffTree HT,int n,int *s1,int *s2); //在HT[1..i-1]选择parent为0且weight 最小的两个结点,其序号分别为s1和s2;
void HuffmanCode(HuffTree HT,int len,HuffCode hc); //生成Huffman编码;
void HuffmanTree(HuffTree HT,int length,HuffCode hc) //Huffman树初始化;
{
int i,s1,s2;
HT[0].Weight = 65535;
for(i = 1;i <= length;i++)
{
HT[i].Weight = hc[i].w;
HT[i].LChild = HT[i].RChild = HT[i].Parent = -1;
}
for(;i < 2*length;i++) //i初值 = length+1;
{
HT[i].LChild = HT[i].RChild = HT[i].Parent = -1;
}
for(i = length+1;i < 2*length;i++)
{
SelectHTNode(HT,i,&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;
}
}
void SelectHTNode(HuffTree HT,int n,int *s1,int *s2) //在HT[1..i-1]选择parent为0且weight 最小的两个结点,其序号分别为s1和s2;
{
int i;
*s1 = *s2 = 0;
for(i = 1;i < n;i++)
{
if(HT[i].Parent == -1)
{
if(HT[*s1].Weight >= HT[i].Weight)
{
*s2 = *s1;
*s1 = i;
}
else if(HT[*s2].Weight > HT[i].Weight) *s2 = i;
}
}
}
void HuffmanCode(HuffTree HT,int len,HuffCode hc) //生成Huffman编码;
{
int i,j,tc,Stack[MaxSize],top = -1;
char flag[MaxSize];
HTNode th;
for(i = 1;i <= len;i++)
{
top = -1; //栈初始化;
j = 0; //hc[i].code串首位置偏移;
th = HT[i]; //当前结点th;
tc = i; //当前结点标记tc;
while(th.Parent != -1)
{ //当前结点th双亲P入栈,由P的孩子是th,确定flag;确定下次结点标记tc; Stack[++top] = th.Parent;
if(HT[th.Parent].LChild == tc) {flag[top] = 'L'; tc = th.Parent;}
if(HT[th.Parent].RChild == tc) {flag[top] = 'R'; tc = th.Parent;}
th = HT[Stack[top]]; //下一结点;
}
while(top != -1)
{
if(flag[top] == 'L') hc[i].code[j++] ='0';
else hc[i].code[j++] ='1';
Stack[top--]; //出栈;
}
hc[i].code[j] ='\0'; //当前串结束;
}
}
int main(void)
{
HuffTree HT; //Huffman树;
HuffCode HC; //Huffman编码;
int i,len;
printf("输入代码数量:"); scanf("%d",&len); system("cls");printf("代码数量:%2d\n\n",len);
printf("输入代码和权值(输入格式为:\"c1[回车]\")\n");
for(i=1;i <= len;i++)
{
while(getchar() != '\n') NULL;
printf("No.%2d: ",i);
HC[i].c = getchar();
scanf("%d",&HC[i].w); }
HuffmanTree(HT,len,HC);
HuffmanCode(HT,len,HC);
printf("\n输出Huffman编码:\n");
for(i = 1;i<=len;i++)
{ printf("\n %c :",HC[i].c);
puts(HC[i].code); }
printf("\n\n输出Huffman树结构:");system("pause");
printf("\nHT[i]:\t权值\t双亲\t左孩子\t右孩子\n");
for(i = 1;i<2*len;i++)
{ if(i <= len) printf("(%c)",HC[i].c);
printf("%2d:\t %2d;\t%2d,\t %2d,\t %2d.\n",
i,HT[i].Weight,HT[i].Parent,HT[i].LChild,HT[i].RChild); } return 0;}
四、测试结果:
代码数量: 8
输入代码和权值(输入格式为:"c1[回车]"
No. 1: a 5
No. 2: b 29
No. 3: c 7
No. 4: d 8
No. 5: e 14
No. 6: f 23
No. 7: g 3
No. 8: h 11
输出Huffman编码:
a :0001
b :11
c :1010
d :1011
e :100
f :01
g :0000
h :001
输出Huffman树结构:请按任意键继续. .
HT[i]: 权值双亲左孩子右孩
(a) 1: 5; 9, -1, -1.
(b) 2: 29; 14, -1, -1.
(c) 3: 7; 10, -1, -1.
(d) 4: 8; 10, -1, -1.
(e) 5: 14; 12, -1, -1.
(f) 6: 23; 13, -1, -1.
(g) 7: 3; 9, -1, -1.
(h) 8: 11; 11, -1, -1.
9: 8; 11, 7, 1.
10: 15; 12, 3, 4.
11: 19; 13, 9, 8.
12: 29; 14, 5, 10.
13: 42; 15, 11, 6.
14: 58; 15, 12, 2.
15: 100; -1, 13, 14.
五、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中,利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中,利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。

将文件CodeFile以紧凑格式显示在终端上,每行50个代码。

同时将此字符形式的编码文件写入文件CodePrint中。

将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。

相关文档
最新文档