哈呼曼编译器设计说明书Word格式.docx

上传人:b****6 文档编号:21381037 上传时间:2023-01-30 格式:DOCX 页数:18 大小:159.84KB
下载 相关 举报
哈呼曼编译器设计说明书Word格式.docx_第1页
第1页 / 共18页
哈呼曼编译器设计说明书Word格式.docx_第2页
第2页 / 共18页
哈呼曼编译器设计说明书Word格式.docx_第3页
第3页 / 共18页
哈呼曼编译器设计说明书Word格式.docx_第4页
第4页 / 共18页
哈呼曼编译器设计说明书Word格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

哈呼曼编译器设计说明书Word格式.docx

《哈呼曼编译器设计说明书Word格式.docx》由会员分享,可在线阅读,更多相关《哈呼曼编译器设计说明书Word格式.docx(18页珍藏版)》请在冰豆网上搜索。

哈呼曼编译器设计说明书Word格式.docx

对于这样的问题,可以利用计算机运算速度快的特点,先搜索查找所有可能出现的情况,再根据题目条件从所有可能的情况中,删除那些不符合条件的解。

由哈夫曼算法的定义可知,初始森林中共有n棵只含有根结点的二叉树。

算法的的第二步是:

将当前森林中的两棵根结点权值最小的二叉树,合并成一棵新的二叉树,每合并一次,森林中就减少一棵树,产生一个新结点。

则要进行n-1次合并,所以共产生n-1个新结点。

由此可知,最终求得的哈夫曼树中一共有2n-1个结点。

其中,n个结点是初始森林中的n个孤立结点。

并且哈夫曼树中没有度数为1的分支的结点。

采用哈夫曼编码方案,即应用哈夫曼树构造使电文的编码总长最短的编码方案。

正文

1.采用类C语言定义相关的数据类型

(1)哈夫曼树的存储结构定义为:

typedefstruct/*字符集的元素结构*/

{chardata;

intweight;

//权值

}elemtype;

typedefstruct/*哈夫曼树的元素结构*/

intflag;

intparent,lchild,rchild;

//左右孩子及双亲指针

}htnode,*huffmantree;

//动态分配数组存储哈夫曼树

typedefchar**HuffmanCode;

//动态分配数组存储哈夫曼编码表

(2)哈夫曼树的存储结构描述:

#include<

stdio.h>

stdlib.h>

string.h>

#definen27/*字符集的容量*/

#defineMAXVALUE1000/*权值的最大值*/

#defineMAXNODE35//哈夫曼树最多节点数

#defineMAXD100

2.各模块的伪码算法:

(1)构造哈夫曼树的算法

voidChuffmanTree(HuffmanTreeHT,HuffmancodeHc,intcnt[],charstr[])

{/*构造哈夫曼树HT,cnt中存放每类字符在电文中出项的频率,str中存放电文中不同类的字符*/

inti,s1,s2;

for(i=1;

i<

=2;

*num-1;

i++)

{

HT[i].lchild=0;

HT[i].rchild=0;

HT[i].parent=0;

HTweight=0;

}

for(i=1;

=2*num;

i++)/*输入num个结点的权值*/

HT[i].weight=cnt[i];

for(i=num+1;

=2*num-1;

{/*在HT[1..i-1]中选择parent为0且权值最小的两个结点*/

selext(Ht,i-1,s1,s2);

HT[s1].parent=i;

HT[s2].parent=i;

Ht[i].lchild=s;

HT[i].rchild=s2;

HT[i].weight=HT[s1].weight+HT[s2].weight;

for(i=0;

=num;

i++)/*输入字符集中字符*/

HC[i].ch=str[i];

i=1;

while(i<

=num)

printf("

字符&

c,次数为:

%d\n"

HC[i].ch,cnt[i++]);

}

(2)求哈夫曼编码(huffmancode)算法:

HuffmanCodehuffmancode(huffmantreeht)

{char*cd;

intc,i,f,start;

HuffmanCodeHC;

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

//分配n个字符编码的头指针向量

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

//分配求编码的工作区间

cd[n-1]='

\0'

;

//编码结束符标志

=n;

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]='

0'

elsecd[--start]='

1'

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

//为第i个字符编码分配空间

strcpy(HC[i],&

cd[start]);

//从cd复制编码(串)到HC

puts(HC[i]);

free(cd);

//释放工作空间

return(HC);

(3)求测试数据的编码(encoding)算法:

voidencoding(huffmantreeht,char**hc)//根据哈夫曼树HT求哈夫曼编码表HC

{inti,j,k;

charsstring[MAXNODE];

clrscr();

flushall();

inputhuffmancode\neg.:

thisisprogrammaismyfavorite:

\n"

);

gets(sstring);

for(i=0;

strlen(sstring);

{for(j=1;

j<

j++)

if(sstring[i]==ht[j].data)

{k=j;

break;

(4)哈夫曼译码算法:

voiddecoding(huffmantreeht)//代码文件的译码

{chara[MAXD];

intm,i;

scanf("

%s"

a);

m=2*n-1;

a[i]!

='

{if(a[i]=='

)m=ht[m].lchild;

elsem=ht[m].rchild;

if(m<

=n)

{printf("

%c"

ht[m].data);

3.函数调用关系图:

4.调试分析:

a.调试中遇到的问题及对问题的解决方法:

在对源程序进行调试时,当输入字符后,应正确判断所输入的字符是否满足程序的需求,且保正所输入字符后所输出语句功能唯一。

则在源程序中加入了一条while()判断语句,若while()判断语句中表达式成立,就重新获取一个字符,然后对while()语句进行重新判断,直到while()判断语句中表达式不成立,就执行switch()语句中于其输入字符相对应的case’’语句.其程序语句如下:

while(ch!

r'

&

ch!

c'

e'

d'

q'

ch=getchar();

/*选取功能*/

switch(ch)

{case'

:

readdata(w);

break;

/*初始化(readdata),读取数据*/

case'

ht=createhuff(w);

/*建立哈夫曼树(createhuff)*/

hc=huffmancode(ht);

encoding(ht,hc);

/*求字符集的哈夫曼编码(huffmancode)和求测试数据的编码(encoding)*/

decoding(ht);

/*译码(decoding)*/

return;

/*程序结束,返回*/

b.算法的时间复杂度和空间复杂度

时间复杂度:

建立哈夫曼树:

O(n³

对文件中正文进行编码:

O(n2)

对文件中的代码进行译码:

O(n)

5测试结果

对下列给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:

“THISPROGRAMISMYFAVORITE“。

字符空格ABCDEFGHIJKLM

频度1866413223210321154757153220

字符NOPQRSTUVWXYZ

频度5763151485180238181161

输入r后:

输入c后:

输入e后:

6.源程序(带注释)

#defineMAXNODE35//哈夫曼树最多节点数

typedefstruct/*字符集的元素结构*/

//左右孩子及双亲节点

//动态分配数组存储哈夫曼编码表

voidreaddata(elemtype*w);

huffmantreecreatehuff(elemtype*w);

char**huffmancode(huffmantreeht);

voidencoding(huffmantreeht,char**hc);

voiddecoding(huffmantreeht);

//初始化readdata,读取数据

voidreaddata(elemtype*w)

{inti;

w[0].data='

'

;

w[0].weight=186;

w[1].data='

a'

w[1].weight=64;

w[2].data='

b'

w[2].weight=13;

w[3].data='

w[3].weight=22;

w[4].data='

w[4].weight=32;

w[5].data='

w[5].weight=103;

w[6].data='

f'

w[6].weight=21;

w[7].data='

g'

w[7].weight=15;

w[8].data='

h'

w[8].weight=47;

w[9].data='

i'

w[9].weight=57;

w[10].data='

j'

w[10].weight=1;

w[11].data='

k'

w[11].weight=5;

w[12].data='

l'

w[12].weight=32;

w[13].data='

m'

w[13].weight=20;

w[14].data='

n'

w[14].weight=57;

w[15].data='

o'

w[15].weight=63;

w[16].data='

p'

w[16].weight=15;

w[17].data='

w[17].weight=1;

w[18].data='

w[18].weight=48;

w[19].data='

s'

w[19].weight=51;

w[20].data='

t'

w[20].weight=80;

w[21].data='

u'

w[21].weight=23;

w[22].data='

v'

w[22].weight=8;

w[23].data='

w'

w[23].weight=18;

w[24].data='

x'

w[24].weight=1;

w[25].data='

y'

w[25].weight=16;

w[26].data='

z'

w[26].weight=1;

27;

{printf("

%c"

w[i].data);

printf("

%d\t"

w[i].weight);

return;

huffmantreecreatehuff(elemtype*w)

{inti,j,x1,x2;

intm1,m2,m;

huffmantreeHT,p;

HT=(huffmantree)malloc((m+1)*sizeof(htnode));

//0号单元未用

p=HT;

p++;

=m;

i++,p++,w++)//初始化HT

{if(i<

p->

data=w->

data;

weight=w->

weight;

else

data='

weight=0;

parent=0;

lchild=0;

rchild=0;

flag=0;

n;

i++)//该循坏开始构造哈夫曼树

{m1=m2=MAXVALUE;

x1=x2=0;

for(j=1;

=n-1+i;

if(p[j].weight<

m1&

p[j].flag==0)

{m2=m1;

x2=x1;

m1=p[j].weight;

x1=j;

elseif(p[j].weight<

m2&

{m2=p[j].weight;

x2=j;

p[x1].parent=n+i;

p[x2].parent=n+i;

p[x1].flag=1;

p[x2].flag=1;

p[n+i].weight=p[x1].weight+p[x2].weight;

p[n+i].lchild=x1;

p[n+i].rchild=x2;

%d,%c,%d,%3d,%3d,%3d,%3d\n"

i,p[i].data,p[i].flag,p[i].weight,p[i].parent,p[i].lchild,p[i].rchild);

if(i%15==0){

getch();

return(HT);

//从叶子到根逆向求哈夫曼编码

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

//分配n个字符的头指针向量

//分配求编码的工作区间

//编码结束符

i++)//逐个字符求哈夫曼编码

//编码结束符位置

c=f,f=ht[f].parent)//从叶子到根逆向求编码

//为第i个字符编码分配空间

//从cd复制编码串到HC

free(cd);

//释放工作区间

voidencoding(huffmantreeht,char**hc)

if(k<

=0||k>

MAXNODE)

thereisn'

tNO.%dchar\n"

i);

continue;

%c\tweight=%3d\t%s\n"

ht[k].data,ht[k].weight,hc[k]);

voiddecoding(huffmantreeht)

main()

{elemtypew[n];

/*字符和频度集合类型*/

charch;

huffmantreeht;

/*哈夫曼树类型*/

HuffmanCodehc;

/*编码类型*/

)/*当键入’q’时程序运行结束*/

总结

在这三周的数据结构课程设计中,我的题目是:

哈夫曼编译码器设计,这三周课程设计中,通过该题目的设计过程,我加深了对树的数据结构以及二叉树的逻辑结构,存储结构的理解,对树的数据结构上基本运算的实现有所掌握,对课本中所学的各种数据结构进一步理解和掌握,学会了如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。

一个人要完成所有的工作是非常困难和耗时的。

在以后的学习中我会更加注意自己各个方面的能力的协调发展。

在课程设计时我遇到了很多的问题,在老师的帮助,和对各种资料的查阅中,将问题解决,培养了我自主动手,独立研究的能力,为今后在学习工作中能更好的发展打下了坚实的基础。

三周的课程设计很短暂,但其间的内容是很充实的,在其中我学习到了很多平时书本中无法学到的东西,积累了经验,锻炼了自己分析问题,解决问题的能力,并学会了如何将所学的各课知识融会,组织,来配合学习,三周中我收益很大,学到很多。

参考文献

1.严蔚敏,陈文博编著.数据结构及应用算法教程,北京:

清华大学出版社,2001

2.苏仕华主编.数据结构自学辅导.北京:

清华大学出版社,2002

3.苏仕华主编.数据结构与算法解析.合肥:

中国科学技术大学生出版社,2004

4.谭浩强编著.C程序设计.北京:

清华大学出版社,1991

附件Ⅰ部分源程序代码

栈的应用——用栈来实行编译(左右括号配对)

算法:

voidpush(stacknode*st,elemtypex)/*将元素x入栈*/

if(st->

top==m)/*判断栈ST是否已满*/

thestackisoverflow!

st->

top=st->

top+1;

stack[st->

top]=x;

voidpop(stacknode*st)/*将栈的栈顶元素出栈*/

{

top-1;

源程序:

#definem20

#defineelemtypechar

typedefstruct/*栈类型的定义*/

elemtyp

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

当前位置:首页 > 幼儿教育 > 少儿英语

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

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