哈夫曼树的结构算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哈夫曼树的结构算法12
利用哈夫曼编码进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统,试为这样的信息收发站写一个哈夫曼编译码系统。
一个完整的系统应具有以下功能:
(1)(1) I:初始化。从终端读入字符集大小 n ,及 n 个字符和 n 个权值,建立哈夫曼树,并将其存于文件hfmtree中。
(2) C:编码。利用已建好的哈夫曼树(如不在内存,则从文件hfmtree中读入),对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中。
(3) D:译码。利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。
(4) P:打印代码文件。将文件codefi1e以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件codeprint中。
(5) T:打印哈夫曼树。将已在内存中的哈夫曼树以直观的方式(树或凹凸表形式)显示在屏幕上,同时将此字符形式的哈夫曼树写入文件treeprint中。
实现提示:
1、用户界面可以设计为“菜单”方式:显示上述功能号,再加上“E”表示结束运性行结束,用户键入一个选择功能字符,则执行相应的功能,此功能执行完毕后再显示此菜单,直至用户选择了“E”为止。
2、在程序的一次执行过程中,第一次执行了I、D 或 C 命令之后,哈夫曼树已经在内存中存在了,不必再读入。每次执行中不一定执行 I 命令,因为文件hfmtree 可能早已建好。
我写的源程序如下:
#include
#include
#include
///////////////////////////////////////////////////////////////////// /////////
/*定义赫夫曼树结点的结构体变量,存放结点的权值、字符、双亲、坐孩子和右孩子*/
typedef struct{
int weight;
char ch; //增加一个域用于存放该节点的字符
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode; //指向赫夫曼编码的指针
///////////////////////////////////////////////////////////////////// /////////
/*本程序用到的函数原型*/
void welcome(); //打印操作选择界面
void HuffmanCoding(HuffmanTree &,char *,int *,int);//建立赫夫曼树的算法
void select(HuffmanTree HT,int j,int *s1,int *s2); //从目前已建好的赫夫曼树中选择parent为0且weight最小的两个结点
void Init(); //输入n个字符及其对应的权值,根据权值建立哈夫曼树
void Coding(); //编码
void Decoding(); //译码
void Print_code(); //打印译码好的代码文件
void Print_tree(); //以凹凸表形式打印哈夫曼树
int Read_tree(HuffmanTree &); //从文件中读入赫夫曼树
void find(HuffmanTree &HT,char *code,char *text,int i,int m);//译码时根据01字符串寻找相应叶子节点的递归算法
void Convert_tree(unsigned char T[100][100],int s,int *i,int j);//将内存中的赫夫曼树转换成凹凸表形式的赫夫曼树
HuffmanTree HT; //全局变量,指向存放赫夫曼树的存储空间
int n=0; //全局变量,存放赫夫曼树叶子结点的数目
int main()
{
char select;
while(1)
{
welcome();
scanf("%c",&select);
switch(select)
{
case 'i':
case 'I':Init();break;
case 'c':
case 'C':Coding();break;
case 'd':
case 'D':Decoding();break;
case 'p':
case 'P':Print_code();break;
case 't':
case 'T':Print_tree();break;
case 'e':
case 'E':exit(1);
default :printf("Input error!\n");
}
getchar();
}
return 0;
}
void welcome() //打印操作选择界面
{
printf("*-----------------------------------------------------*\n"); printf("| What do you want to do? |\n"); printf("|-----------------------------------------------------|\n"); printf("| |\n ");
printf("| I--------------------------Init the Huffman tree. |\n"); printf("| C--------------------------Code your file. |\n"); printf("| D--------------------------Decode the code. |\n"); printf("| P--------------------------Print the codefile. |\n"); printf("| T--------------------------Print the Huffman tree. |\n"); printf("| |\n ");
printf("*-----------------------------------------------------*\n ");
}
///////////////////////////////////////////////////////////////////// /////////////////
/*初始化函数,输入n个字符及其对应的权值,根据权值建立哈夫曼树,并将其存于文件hfmtree中*/
void Init()
{
FILE *fp;
int i,n,w[52]; //w数组存放n个字符的权值
char character[52]; //存放n个字符
printf("\n输入字符个数 n:");
scanf("%d",&n); //输入字符集大小
printf("输入%d个字符及其对应的权值:\n",n);
for (i=0;i {