一、需求分析
功能需求:
设计并实现一个写一个哈夫曼码的编/译码系统,系统功能包括:
(1)I:初始化(Initialization)。从终端读入字符集大小 n,以及 n 个字符和 n 个权值,建立哈夫曼树,并将它存于文件 hfmTree 中;
(2)E:编码(Encoding)。利用以建好的哈夫曼树(如不在内存,则从文件 hfmTree 中读入),对文件ToBeTran 中的正文进行编码,然后将结果存入文件CodeFile 中;
(3)D:译码(Decoding)。利用已建好的哈夫曼树将文件 CodeFile 中的代码进行译码,结果存入文件TextFile 中;
(4)P:印代码文件(Print)。将文件 CodeFile 以紧凑格式显示在终端上,每行 50 个代码。同时将此字符形式的编码文件写入文件 CodePrin 中;
(5)T:印哈夫曼树(Tree printing)。将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint 中。
界面需求:
可以输入哈夫曼编码所需的字符及权值,打印出哈夫曼树结构和各个字符的哈夫曼编码。读取字符串可以进行编码和解码并输出,输出在TXT文件中展示
二、概要设计
模块层次结构设计
Initialhuffman()进行初始化
Encoding()进行编码
Decoding()进行解码
Codeprint()将CodeFile.txt的数据紧凑打印在终端上
接口设计
int MinVal(HuffmanTree tree,int i);//在前i个节点中选择parent为-1且weight最小的结点,返回其序号
void Select(HuffmanTree tree,int i,int *s1,int *s2);//设定s1序号更小
void Display(HuffmanTree tree);//打印哈夫曼树并将其输出至TreePrint.txt(直观)和hfmTree.txt(供读取)文件
int huffcode(HuffmanTree tree, huffmanCodex code);//编码并写入文件中
int incode(HuffmanTree tree, huffmanCodex code); //对每一个字符进行编码
int decode(HuffmanTree tree);//用树对CodeFile.txt进行解码并输出至TextFile.txt中
void CodePrint();//将CodeFile.txt中的数据改为50个一行并存入CodePrin.txt中
数据结构设计
struct HTNode{
char ch;
int weight,lchild,rchild,parent;
};//哈夫曼树结点结构
typedef struct{
struct HTNode ht[1024];
int htsize;
}Huffman,*HuffmanTree;//哈夫曼树结构
typedef struct {
char bits[50];
char ch;
}huffmanCode,*huffmanCodex;//哈夫曼编码结构
三、详细设计
Initialhuffman.cpp内容如下:
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
struct HTNode{
char ch;
int weight,lchild,rchild,parent;
};//哈夫曼树结点结构
typedef struct{
struct HTNode ht[1024];
int htsize;
}Huffman,*HuffmanTree;//哈夫曼树结构
//在前i个节点中选择parent为-1且weight最小的结点,返回其序号
int MinVal(HuffmanTree tree,int i){
int j,k,min=-1;
for(j=0;j<i;j++){
if(tree->ht[j].parent==-1&&min==-1){
min=tree->ht[j].weight; //将第一个双亲为空的点置为最小值
k=j;
break;
}
}
for(j=0;j<i;j++){
if(tree->ht[j].parent==-1&&tree->ht[j].weight<min){
min=tree->ht[j].weight;
k=j;
}
}
tree->ht[k].parent=-2;//置双亲非空
return k;
}
void Select(HuffmanTree tree,int i,int *s1,int *s2){
//设定s1序号更小
int s;
*s1 = MinVal(tree,i);
*s2 = MinVal(tree,i);
if(*s1>*s2){
s=*s1;
*s1=*s2;
*s2=s;
}
}
void Display(HuffmanTree tree){
int i;
//定义文件指针
FILE *f = NULL,*fp = NULL;
//打开文件
f = fopen("TreePrint.txt","w");
fp =fopen("hfmTree.txt","w");
if(f==NULL||fp==NULL)
{
printf("文件读取失败!\n");
}
char buf[1024];
//写文件
strcpy(buf,"下标 字符 权值 左孩子 右孩子 双亲\n");
fputs(buf,f);
fprintf(fp,"%d\n",tree->htsize);
printf("下标 字符 权值 左孩子 右孩子 双亲\n") ;
for(i=1;i<=tree->htsize;i++){
//将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中
fprintf(f,"%d",i);
fprintf(f,"%12c",tree->ht[i].ch);
fprintf(f,"%12d",tree->ht[i].weight);
fprintf(f,"%12d",tree->ht[i].lchild);
fprintf(f,"%12d",tree->