哈夫曼编码与译码

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、设计思想

程序要求:

利用哈夫曼树对字符串进行编码,要求每个字符有自己唯一的编码。将得到的一串字串译成0、1编码后存到一个文件夹中,然后再从这个文件夹中读出这串编码进行解码。

实现方法:

输入一串字符,要求字符的区间为大写的26个英文字母,将获得的串字符用计算权值的函数(jsquanzhi())进行字符统计,统计出现的字符种数以及每种字符出现的次数,将该种字符出现的次数作为它的权值。将出现的字符的权值和该字符依次分别赋给两个结构体HT和HC,利用HT(节点)权值的大小建立哈夫曼树,首先用选择函数select()函数选择两个权值最小的字符作为叶子节点,创建一个新的节点作为这两个叶节点的父节点,被选中的节点给他的HT[i].parent赋值是他下次不再被选中,父节点的权值为,子节点的权值之和。然后将该将父节点放入筛选区中,再进行选择(被选过的不再被使用),直到所有的节点都被使用,这样一个哈夫曼树就被建立了。根据每个字符在哈夫曼书中的位置来编译每个字符的0、1密文代码,从叶节点判断该叶节点是其父节点的左右字左字为‘0’,右子为‘1’,在判断父节点是上级父节点的左右子直至根节点,将生成的0、1字符串按所表示的字符倒序存入HC相应的字符的bins[]数组。

重新一个一个字符的读取输入的字符串,按照字符出现的顺序将它转为0、1代码并存到一个txt文件夹中去。解码时从文件夹中,一个一个字符的读出那串0、1代码赋给一个临时字符串cd[],用该字符串与每个字符的HC[i].bins密文比较,直到与一个字符的密文相同时,译出该字符,将字符存放在临时字符数组tempstr[]中,清空临时字符串继续读取0、1代码进行翻译,直至文件密文结束为止。于是就得到了原先被加密的那串字符串。

二、算法流程图

三、源代码

// hafuman.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "stdlib.h"

#include "string.h"

#include "stdio.h"

#define n 100 //叶节点的个数小等于n

#define m 2*n-1 //总结点的个数为m=2*n-1

int num; //定义一个全局变量用于存放字符种类个数

typedef struct //结构体用于存放树节点包括节点的父节点、左子、右子以及权值{ int weight;

int parent,lchild,rchild;

}HTNode;

typedef HTNode HafumanTree[m+1]; //重命名HTNode

typedef struct //结构体由于存放每个字符的密文和长度{char ch;

char bits[10];

int len;

}CodeNode;

typedef CodeNode HafumanCode[n+1]; //重命名CodeNode

int _tmain(int argc, _TCHAR* argv[])

{int quan[27]; //声明一个数组用以存放26字符的权值

char getstr[300],str[27];

//声明两个字符串数组一个用于存输入一个由于存放输入中含有的字符

char *s; //声明一个char型指针用于指向字符HafumanTree HT; //声明m+1个树节点

HafumanCode HC; //声明n+1个code

int jisuanquan(char *s,int quan[],char str[]); //声明需要调用的函数

void gjhafumantree(HafumanTree HT,HafumanCode HC,int quan[],char str[]);

void Hafumanencode(HafumanTree HT,HafumanCode HC);

void coding(HafumanCode HC,char *str);

char *decode(HafumanCode HC);

printf("请输入要加密的字符串:\n");

gets(getstr); //获得输入的字符串

num=jisuanquan(getstr,quan,str); //统计字符串中含有字符种类个数

//printf("%d\n",num);

gjhafumantree(HT,HC,quan,str); //根据字符权值构建哈夫曼树Hafumanencode(HT,HC); //根据哈夫曼树确定每个字符的code coding(HC,getstr); //将字符串译码存入文件夹

s=decode(HC); //将暗文解码

printf("解密为:\n");

printf("%s\n",s);

system("pause");

return 0;

}

//函数

int jisuanquan(char *s,int quan[],char str[]) //计算字符串中字符权值

{char *p;

int i,j,k,quantemp[27];

for(i=1;i<27;i++) //将所有字符的权值赋成0 {quantemp[i]=0;}

for(p=s;*p!='\0';p++) //判断字符串是否结束

{if(*p>='A'&&*p<='Z') //判断字符是否为26字母{k=*p-64; //看是26个字符中的哪个字符

quantemp[k]++; //字符权值加1

}

}

j=0;

for(i=1,j=0;i<27;i++)

{if(quantemp[i]!=0)

{j++; //用于统计字符种类个数

str[j]=i+64; //str按字母表顺序存储出现过的字符quan[j]=quantemp[i];

}

}

return j;

}

相关文档
最新文档