哈夫曼树的应用Word格式文档下载.docx

上传人:b****5 文档编号:16196608 上传时间:2022-11-21 格式:DOCX 页数:26 大小:238.34KB
下载 相关 举报
哈夫曼树的应用Word格式文档下载.docx_第1页
第1页 / 共26页
哈夫曼树的应用Word格式文档下载.docx_第2页
第2页 / 共26页
哈夫曼树的应用Word格式文档下载.docx_第3页
第3页 / 共26页
哈夫曼树的应用Word格式文档下载.docx_第4页
第4页 / 共26页
哈夫曼树的应用Word格式文档下载.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

哈夫曼树的应用Word格式文档下载.docx

《哈夫曼树的应用Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《哈夫曼树的应用Word格式文档下载.docx(26页珍藏版)》请在冰豆网上搜索。

哈夫曼树的应用Word格式文档下载.docx

2、本演示程序中,用户可以输入键盘中的任意字符,长度为任意长,字符输入顺序不限,且允许出现重码

3、演示程序以用户与计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,相应的输入数据(可虑去输入中的非法字符)和运算结果显示在其后。

4、本演示程序中,当用户选择的功能错误时,系统会输出相应的提示。

5、在本系统中,用户可以对任意长的字符串可进行编码/译码。

6、程序执行的命令包括:

 1)初始化(I)   2)编码(E)    3)译码(D)

4)印代码文件(P) 5)印哈夫曼树(T) 6)退出(Q)

7、测试数据:

(二)、概要设计

为实现上述程序功能,应以指针存储结点。

为此,需要定义一个抽象数据类型。

1.抽象数据类型定义为:

ADTHuffmanTree{

数据对象:

D={ai|ai∈CharSet,i=1,2,……,n,n≥0}

数据关系:

R={<

ai-1,ai>

ai-1,ai∈D,ai-1基本操作P:

HuffmanTree();

构造函数

~HuffmanTree();

析构函数

Initialization(intWeightNum);

操作结果:

构造哈夫曼树。

Encoder()

初始条件:

哈夫曼树已存在或者哈夫曼树已存到文件中。

对字符串进行编码

Decoder();

哈夫曼树已存在且已编码。

对二进制串进行译码

Print()

编码文件已存在。

把已保存好的编码文件显示在屏幕

TreePrinting()

哈夫曼树已存在。

将已在内存中的哈夫曼树以直观的方式显示在终端上

2.本程序包含三个模块:

1)主程序模块:

voidmain(){

初始化;

do{

接受命令;

处理命令;

}while(“命令”=”退出”)

}

2)、建树模块——实现定义的抽象数据类型

3)、编/译码模块——实现字符串的编/译码

各模块之间的调用关系如下:

主程序模块

建树模块

编/译码模块

程序代码如下

//程序名:

HuffmanTree.h

//程序功能:

哈夫曼树类的头文件(并用其来实现编/译码)

//作者:

蔡丽敏

//日期:

2008.12.27

//版本:

1.0

//对应类实现文件:

HuffmanTree.cpp

//对应主程序文件:

main.cpp

1//程序名:

HuffmanTree.h

2//程序功能:

哈夫曼树类的头文件(并用其来实现编/译码)

3

4//对应类实现文件:

HuffmanTree.cpp

5//对应主程序文件:

main.cpp

6

7

8

9#include<

iostream>

10#include<

fstream>

11#include<

string>

12usingnamespacestd;

13structHuffmanNode//定义哈夫曼树各结点

14{

15intweight;

//存放结点的权值,假设只考虑处理权值为整数的情况

16intparent;

//记录结点父亲位置,-1表示为根结点,否则表示为非根结点

17intlchild,rchild;

//分别存放该结点的左、右孩子的所在单元的编号

18};

19classHuffmanTree//建立哈夫曼树类

20{

21private:

22HuffmanNode*Node;

//哈夫曼树中结点的存储结构

23char*Info;

//用来保存各字符信息

24intLeafNum;

//树中的叶子结点总数

25public:

26HuffmanTree();

//构造函数

27~HuffmanTree();

//析构函数

28voidInitialization(intWeightNum);

//初始化函数:

根据WeightNum个权值建立一棵哈夫曼树

29voidEncoder();

//编码函数:

利用构造好的哈夫曼树对字符进行编码

30voidDecoder();

//译码函数:

对二进制串进行译码

31voidPrint();

//印文件函数:

把已保存好的编码文件显示在屏幕

32voidTreePrinting();

//印哈夫曼树函数:

将已在内存中的哈夫曼树以直观的方式显示在终端上

33};

HuffmanTree.cpp

实现哈夫曼树类的源文件(并用其来实现编/译码)

蔡丽敏

1#include"

HuffmanTree.h"

2#include<

3usingnamespacestd;

45/**///////////////////////////////////////////////////////////////////////////////

6//构造函数

7//函数功能:

将结点指针初始化为NULL

8//函数参数:

9//参数返回值:

10HuffmanTree:

:

HuffmanTree()

11{

12Node=NULL;

//将树结点初始化为空

13Info=NULL;

//将字符数组初始化为空

14LeafNum=0;

//将叶子数初始化为0

15}

16/**///////////////////////////////////////////////////////////////////////////////

17//析构函数

18//函数功能:

将所有结点的空间释放

19//函数参数:

20//参数返回值:

21HuffmanTree:

~HuffmanTree()

22{

23delete[]Node;

//释放结点空间

24delete[]Info;

//释放字符存储空间

25}

26/**///////////////////////////////////////////////////////////////////////////////

27//初始化函数

28//函数功能:

从终端读入字符集大小n,以及n个字符和n个权值,

29//建立哈夫曼树,并将它存放在文件hfmTree中.

30//函数参数:

intWeightNum表示代码个数

31//参数返回值:

32voidHuffmanTree:

Initialization(intWeightNum)//初始化

33{

34inti,j,pos1,pos2,max1,max2;

//

35

36Node=newHuffmanNode[2*WeightNum-1];

//WeightNum权值对应的哈夫曼树中的结点总数为2*WeightNum-1个

37//Info=newchar[2*WeightNum-1];

38Info=newchar[WeightNum];

39for(i=0;

i<

WeightNum;

i++)

40{

41cout<

<

"

请输入第"

i+1<

个字符值"

;

42getchar();

//丢弃字符'

\t'

与'

\n'

43Info[i]=getchar();

//输入一个字符,主要是考虑输入空格而采用这种形式的

44//cin>

>

Info[i];

45getchar();

46cout<

请输入该字符的权值或频度"

47cin>

Node[i].weight;

//输入权值

48Node[i].parent=-1;

//为根结点

49Node[i].lchild=-1;

//无左孩子

50Node[i].rchild=-1;

//无右孩子

51}

52

53for(i=WeightNum;

2*WeightNum-1;

i++)//表示需做WeightNum-1次合并

54{

55pos1=-1;

56pos2=-1;

//分别用来存放当前最小值和次小值的所在单元编号

57max1=32767;

//32767为整型数的最大值

58max2=32767;

//分别用来存放当前找到的最小值和次小值

59

60for(j=0;

j<

i;

j++)//在跟节点中选出权值最小的两个

61if(Node[j].parent==-1)//是否为根结点

62if(Node[j].weight<

max1)//是否比最小值要小

63{

64max2=max1;

//原最小值变为次小值

65max1=Node[j].weight;

//存放最小值

66pos2=pos1;

//修改次小值所在单元编号

67pos1=j;

//修改最小值所在单元编号

68}

69else

70if(Node[j].weight<

max2)//比原最小值大但比原次小值要小

71{

72max2=Node[j].weight;

//存放次小值

73pos2=j;

//修改次小值所在的单元编号

74}

75//for

76Node[pos1].parent=i;

//修改父亲位置

77Node[pos2].parent=i;

78Node[i].lchild=pos1;

//修改儿子位置

79Node[i].rchild=pos2;

80Node[i].parent=-1;

//表示新结点应该是根结点

81Node[i].weight=Node[pos1].weight+Node[pos2].weight;

82}//for

83LeafNum=WeightNum;

84

85

86charch;

87cout<

是否要替换原来文件(Y/N):

88cin>

ch;

89if(ch=='

y'

||ch=='

Y'

90{

91ofstreamfop;

//以二进制方式打开hfmTree.dat文件,并当重新运行时覆盖原文件

92fop.open("

hfmTree.dat"

ios:

out|ios:

binary|ios:

trunc);

93if(fop.fail())//文件打开失败

94cout<

文件打开失败!

\n"

95fop.write((char*)&

WeightNum,sizeof(WeightNum));

//写入WeightNum

96for(i=0;

i++)//把各字符信息写入文件

97{

98fop.write((char*)&

Info[i],sizeof(Info[i]));

99flush(cout);

100}

101for(i=0;

i++)//把个节点内容写入文件

102{

103fop.write((char*)&

Node[i],sizeof(Node[i]));

104flush(cout);

105}

106fop.close();

//关闭文件

107}

108cout<

哈夫曼树已构造完成。

109}//Initialization

110

111/**///////////////////////////////////////////////////////////////////////////////

112//编码函数

113//函数功能:

利用已建立好的哈夫曼树(如不在内存,则从文件hfmTree中读入),

114//对文件ToBeTran中的正文进行编码,然后将结果代码存(传输)到文件CodeFile中.

115//函数参数:

116//参数返回值:

117voidHuffmanTree:

Encoder()

118{

119if(Node==NULL)//哈夫曼树不在内存,从文件hfmTree中读入

120{

121ifstreamfip;

//以二进制方式打开hfmTree.dat文件

122fip.open("

in);

123if(fip.fail())//文件打开失败

124{

125cout<

126return;

//结束本函数

127}

128fip.read((char*)&

LeafNum,sizeof(LeafNum));

//读取叶子数

129Info=newchar[LeafNum];

130Node=newHuffmanNode[2*LeafNum-1];

131for(inti=0;

LeafNum;

i++)//读取字符信息

132fip.read((char*)&

133for(i=0;

2*LeafNum-1;

i++)//读取结点信息

134fip.read((char*)&

135}

136

137char*Tree;

//用于存储需编码内容

138inti=0,num;

139charChoose;

//让用户选择读取文件或重新输入需编码内容

140cout<

你要从文件中读取内容

(1),还是重新输入

(2):

141cin>

Choose;

142if(Choose=='

1'

)//读取文件ToBeTran.txt

143{

144ifstreamfip1("

ToBeTran.txt"

);

145if(fip1.fail())//文件不存在

146{

147cout<

文件打开失败!

148return;

149}

150charch;

151intk=0;

152while(fip1.get(ch))

153{

154k++;

//计算CodeFile中代码长度

155}

156fip1.close();

157

158Tree=newchar[k+1];

159ifstreamfip2("

160

161k=0;

162while(fip2.get(ch))

163{

164Tree[k]=ch;

//读取文件内容,并存到Tree中

165k++;

166}

167fip2.close();

168Tree[k]='

\0'

//结束标志

169cout<

需编码内容为:

170cout<

Tree<

endl;

171}//if(Choose=='

172

173else//Choose!

='

重新输入

174{

175stringtree;

//用于输入需编码内容,由于string类对象可以输入任意长度,

176//所以先利用这个对象输入,再转存在Tree中

177

178cin.ignore();

179cout<

请输入需要编码的内容(可输入任意长,结束时请按2下回车):

180getline(cin,tree,'

//输入任意长字符串,

181//getline以回车('

)作为结束符,第一次按回车表示字符串结束,第二次按回车才开始输出。

182while(tree[i]!

183i++;

184num=i;

//计算tree长度

185i=0;

186Tree=newchar[num+1];

187while(tree[i]!

)//将tree中的字符转存到Tree中

188{

189Tree[i]=tree[i];

190i++;

191}

192Tree[i]='

//结束标志符

193}

194

195ofstreamfop("

CodeFile.dat"

//存储编码后的代码,并覆盖原文件

196i=0;

197intk=0;

198char*code;

199code=newchar[LeafNum];

//为所产生编码分配容量为LeafNum的存储空间

200//因为不等长编码中最长的编码一定不会超过要求编码的字符个数

201while(Tree[k]!

)//对每一个字符编码

202{

203intj,start=0;

204for(i=0;

205if(Info[i]==Tree[k])//求出该文字所在单元的编号

206break;

207j=i;

208while(Node[j].parent!

=-1)//结点j非树根

209{

210j=Node[j].parent;

//非结点j的双亲结点

211if(Node[j].lchild==i)//是左子树,则生成代码0

212code[start++]='

0'

213else//是右子树,则生成代码1

214code[start++]='

\

215i=j;

216}

217code[start]='

//置串结束符

218

219

220for(i=0;

start/2;

i++)//对二进制序列进行逆置

221{

222j=code[i];

223code[i]=code[start-i-1];

224code[start-i-1]=j;

225}

226i=0;

227while(code[i]!

)//存储代码

228{

229fop<

code[i];

230i++;

231}

232k++;

233}

234fop.close();

235cout<

已编码!

且存到文件CodeFile.dat中!

\n\n"

236}//Encode

237

238/**///////////////////////////////////////////////////////////////////////////////

239//译码函数

240//函数功能:

利用已建好的哈夫曼树,对传输到达的CodeFile中的数据代码进行译码,

241//将译码结果存入文件Te

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

当前位置:首页 > 小学教育 > 英语

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

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