一、 需求分析
1、 本程序在初始化字符集后应能进行字符文件的编码、译码功能。
2、 演示程序应以用户和计算机对话的方式执行,即在计算机终端上显示
提示信息之后,由用户在键盘上输入程序中规定的命令,相应的输入
数据和结果显示在其后面。
3、 程序执行的命令包括:
(1)初始化;(2)编码;(3)译码;(4)印编码文件;(5)退出程序;
4、 测试数据
二、 概要设计
1. 哈夫曼树的抽象数据类型定义:
(1) 哈夫曼树的结点类型:
在哈夫曼树的结点类型中应该存放权值、左儿子链、右儿子链,另外还有设置
父结点链,这样做是为了在生成哈夫曼树时,能方便地由儿子结点找到父结点。
(2)基本操作:
HaffmanTree(); 构造函数
~HaffmanTree(); 析构函数
Initialization(); 初始化,建立一棵哈夫曼树
Encoding();
利用构造好的哈夫曼树对字符文件进行编码
Decoding();
对编码文件中的 01 串进行译码
Print();
把已保存好的编码文件显示在终端上
(3)本程序包括三个模块:
1)主程序模块:
int main()
{
初始化;
While(“命令”==“退出”)
{
哈夫曼树初始化
编码
译码
打印编码文件
}
}
2)哈夫曼树类定义模块:对结构、变量及函数进行声明
3)哈夫曼树类实现模块:实现各个成员函数的功能
三、详细设计
1、结点类型和哈夫曼树的类定义:
struct HaffmanNode
{
//定义哈夫曼树各结点
int weight;
int parent;
int lchild,rchild;
};
class HaffmanTree
{
private:
//存放结点的权值
//记录结点父亲位置,0 表示为根结点,否则表示为非根结点
//分别存放该结点的左、右孩子的所在单元的编号
//建立哈夫曼树类
HaffmanNode *Node;
char *Letter;
int Num;
//哈夫曼树中结点的存储结构
//用来保存各字符
//树中的叶子结点总数
public:
HaffmanTree();
~HaffmanTree();
void Initialization();
void Encoding();
void Decoding();
void Print();
};
//构造函数
//析构函数
//初始化函数:建立一棵哈夫曼树
//编码函数:利用构造好的哈夫曼树对字符进行编码
//译码函数:对 01 串进行译码
//打印编码函数:把已保存好的编码文件显示在终端上
2、哈夫曼树类中各个成员函数的具体实现部分:
// 函数功能:建立一棵哈夫曼树
// 函数参数:无
// 参数返回值:无
void HaffmanTree::Initialization()
//初始化
{
cout<<"请输入字符集大小:";
cin>>Num;
int i,j;
int min1,min2;
//min1,min2 分别表示最小、次小的权值
int x1,x2;
//x1,x2 分别表示当前分支结点的左右儿子
Node=new HaffmanNode[2*Num-1];
//Num 个权值对应的哈夫曼树中的结点总数为 2*Num-1 个
Letter=new char[Num];
//对应有 Num 个字符
for(i=0;i
>Letter[i];
//输入字符
cin>>Node[i].weight;
//输入权值
Node[i].parent=0;
//根结点为空
Node[i].lchild=-1;
//左孩子为空
Node[i].rchild=-1;
//右孩子为空
for(i=0;imin2=min1;
//原最小值变为次小值
min1=Node[j].weight;
//存放最小值
x2=x1;
x1=j;
}
//修改次小值所在单元编号
//修改最小值所在单元编号
else if(Node[j].weight
// 函数功能:利用构造好的哈夫曼树对字符进行编码
// 函数参数:无
// 参数返回值:无
void HaffmanTree::Encoding()
//编码函数
{
char *Word=new char[MAX];
ifstream fip("ToBeTran.txt");
char ch;
int i=0;
while(fip.get (ch))
{
}
Word[i]=ch;
i++;
fip.close();
Word[i]='\0';
ofstream fop("CodeFile.txt",ios::trunc);
//存储编码后的代码,并覆盖原文件
int k=0;
char *bit=new char[Num+1];
//为所产生编码分配容量为 Num 的存储空间
while(Word[k]!='\0')
//对每一个字符编码
{
int j,start=Num-1;
for(i=0;i
bit[start--]='0';
else
//是右子树,则生成编码 1
bit[start--]='1';
i=j;
}
start++;
bit[Num]='\0';
while(bit[start]!='\0')
{
}
fop<