}
char * hfmbm(char *str)
{//哈夫曼编码函数 参数:待编码字符串!
int i=0;//统计字符串字符数
int j=i;
char *p=str;//备份字符串首地址
while(*str)//统计字符数
{
i++;
str++;
}
//printf('%d',i);
tree *hfmtree=(tree*)malloc(sizeof(tree)*(2*i-1));//根据字符数开辟可用空间
str=p;
tree *pp=hfmtree;//备份哈夫曼数组首地址
chushihuahmf(hfmtree,str,i);//根据ascll码制定权值并依此构造数组(根据实际情况可自行修改)
hfmtree=pp;
gettree(hfmtree,2*i-1,i);//构造一个哈夫曼树
tre=&hfmtree[2*i-2];//得到哈夫曼树
bianltree(tre);//通过哈夫曼树编码 并保存在编码
char *restr=(char *)malloc(sizeof(char)*i*11);//开辟编码后的字符串地址
int k=0;
p=restr;
while(k
{//通过遍历 编码映射表 编码字符 通过映射表的字符匹配后返回编码
int b=0;
while(b
{
if (hfm[b].date==str[k])
{
for (int j=0;j
{
*restr=hfm[b].bianm[j];
restr++;
}
break;
}
b++;
}
k++;
}
*restr='\0';
restr=p;
printf('编码完成:\n%s\n',restr);
return restr;
}
void hfmjm(char *hmf)
{//哈夫曼解码 参数哈夫曼编码后的数据串
tree *p=tre;//得到哈夫曼树
while(*hmf)
{
if (*hmf=='0')//编码为0走左子树
{
tre=tre->zuo;
if (tre->min)//为叶子节点
{
printf('%c',tre->date);//输出编码
tre=p;
}
hmf++;
continue;
}
if (*hmf=='1')//编码为1走右子树
{
tre=tre->you;
if (tre->min)
{
printf('%c',tre->date);
tre=p;
}
hmf++;
continue;
}
printf('不能识别编码:%c\n',*hmf);
return;
}
printf('\n');
tre=p;//还原哈夫曼树
//注:本解码是根据哈夫曼树解码 本程序还可以根据编码映射表解码
}
int _tmain(int argc, _TCHAR* argv[])
{
char *ch='abcd@#$3456asd';
printf('待编码数据位:%s\n',ch);
printf('编码格式:\n');
char *str=hfmbm(ch);
printf('解码:\n');
hfmjm(str);
//////解码测试:只要输入编码映射表(struct shmf结构体)有的编码 就能实现解码!
printf('\n解码测试:请根据已有编码格式输入编码\n');
char hmf[100];
gets(hmf);
printf('解码:\n');
hfmjm(hmf);
return 0;
}
测试效果1:
测试效果2:
函数说明:
char * hfmbm(char*str)函数是完成哈夫曼树构造的函数,用户只需传入一个带编码的字符串就可,本函数就可根据字符串开辟数组空间,并构造哈夫曼树。数据结构哈夫曼树
void chushihuahmf(tree *hfmtree,char *str,inti)函数是初始化哈夫曼树权值的函数,因为我们构造时需要指定构造规则(即权值),本函数为了方便,直接使用ascll码作为权值构造,本函数可根据实际情况修改。
void hfmjm(char *hmf)函数是解码函数,通过传入有效编码解码出字符串!
从效果图中,我们发现相同元素有不同的编码,不过这不影响编码与解码,但从空间、时间角度应该避免这种情况,篇幅有效,本文将不再处理,在本例中由于有映射表,所有可以通过遍历映射表删除重复元素。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-27154-4.html
国家不会不在乎
我觉得这样是很有道理的
大企鹅呢
我们都来帮忙了