永发信息网

求哈夫曼编码/译码

答案:1  悬赏:80  手机版
解决时间 2021-06-06 06:48
要求输入叶子节点个数,权值。实现编码和译码。
最佳答案

说明: 叶子节点:"a","e","r","t","d","f",对应权重为8,4,6,3,1,1


测试数据 strtest1="01011101111100011"



#include "stdafx.h"


#include <stdio.h>
#include <string.h>
#define N 50 //叶子结点数/
#define M 2*N-1 //树中结点总数/


typedef struct
{
char data[5]; //结点值/
int weight; //权重/
int parent; //双亲结点/
int lchild; //左孩子结点/
int rchild; //右孩子结点/
} HTNode;


typedef struct
{
char cd[N]; //存放哈夫曼码/
int start;
} HCode;


void CreateHT(HTNode ht[],int n)
{
int i,k,lnode,rnode;
int min1,min2;
for (i=0;i<2*n-1;i++) //所有结点的相关域置初值-1/
ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
for (i=n;i<2*n-1;i++) //构造哈夫曼树/
{
min1=min2=32767; //lnode和rnode为最小权重的两个结点位置/
lnode=rnode=-1;
for (k=0;k<=i-1;k++)
if (ht[k].parent==-1) //只在尚未构造二叉树的结点中查找/
{
if (ht[k].weight<min1)
{
min2=min1;rnode=lnode;
min1=ht[k].weight;lnode=k;
}
else if (ht[k].weight<min2)
{
min2=ht[k].weight;rnode=k;
}
}
ht[lnode].parent=i;ht[rnode].parent=i;
ht[i].weight=ht[lnode].weight+ht[rnode].weight;
ht[i].lchild=lnode;ht[i].rchild=rnode;
}
}


void CreateHCode(HTNode ht[],HCode hcd[],int n)
{
int i,f,c;
HCode hc;
for (i=0;i<n;i++) //根据哈夫曼树求哈夫曼编码/
{
hc.start=n;c=i;
f=ht[i].parent;
while (f!=-1) //循序直到树根结点/
{
if (ht[f].lchild==c) //处理左孩子结点/
hc.cd[hc.start--]='0';
else //处理右孩子结点/
hc.cd[hc.start--]='1';
c=f;f=ht[f].parent;
}
hc.start++; //start指向哈夫曼编码最开始字符/
hcd[i]=hc;
}
}


void DispHCode(HTNode ht[],HCode hcd[],int n)
{
int i,k;
int sum=0,m=0,j;
printf(" 输出哈夫曼编码:\n"); //输出哈夫曼编码/
for (i=0;i<n;i++)
{
j=0;
printf(" %s:\t",ht[i].data);
for (k=hcd[i].start;k<=n;k++)
{
printf("%c",hcd[i].cd[k]);
j++;
}
m+=ht[i].weight;
sum+=ht[i].weight*j;
printf("\n");
}
printf("\n 平均长度=%g\n",1.0*sum/m);
}
int findsubstr(char* S, int cS, HCode hcd[],int n, int &pos)
{
int i,k, j;
if (pos > cS) return -1;
for (i=0;i<n;i++)
{
j = pos;
for (k=hcd[i].start;k<=n;k++)
{
if (S[j] == hcd[i].cd[k])
j++;
else
break;
}
if (k > n)
{
pos = j;
return i;
}
}
return -1;
}


bool Recode(char* S, int cS, HTNode ht[],HCode hcd[],int n){
char strresult[80];
strcpy(strresult,"");
int pos = 0;
while (pos < cS)
{
int result = findsubstr(S, cS, hcd, n, pos);
if (result != -1)
{
strcat(strresult, ht[result].data);
}
else
return false;
}
printf("译码结果为:%s\n\n", strresult);
return true;
}
void main()
{
int i, n=6;
char *str[]={"a","e","r","t","d","f"};
int fnum[]={8,4,6,3,1,1};


HTNode ht[M];
HCode hcd[N];
for (i=0; i<n; i++)
{
strcpy(ht[i].data, str[i]);
ht[i].weight=fnum[i];
}
printf("\n");
CreateHT(ht,n);
CreateHCode(ht,hcd,n);
DispHCode(ht,hcd,n);
printf("\n");


char* strtest1="01011101111100011";
printf("破译原文是:%s\n", strtest1);
int clength = strlen(strtest1);
if (!Recode(strtest1, clength, ht, hcd, n))
printf("译密失败\n");


}

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
女人不喜欢真诚的男人吗?
一个数学问题.紧急!!
该如何面对这可怕的世界?
前进区佳木斯晨丝坊旗舰店在什么地方啊,我要
测试卡上显示57要很久才可以进入BIOS
问问..在本命年结婚是否适合..
搜搜一天能赚几经验?
奔腾b50图片
梦幻吃人参果有数量限制没有?
请问注册一个yagamelife.com的域名有价值吗?
DNF白手带什么鞋
魔域今天打怪为什么去血少?
在家用网吧代理有风险不?
哪里能下到方大同的手机主题...?
掇刀区荆门宜草堂大药房地址在什么地方,想今
推荐资讯
爱上他他不爱我怎么办。
最近眼睛总是胀痛,眼睛胀痛勒原因是啥子?咋
物理牙签穿纸实验
在面对不一样的人时,人人都有缺点你该怎样对
简单的魔方复原公式
大话3二转110敏力男人如何快速冲级?
丝路英雄任务,怎么还不能领取奖励啊?
三国谁能带带我
NVIDIA GeForce 9500 GT这款显卡怎么样?
配一台专门用来作图的电脑,在线等。
天涯呐女子唱完呐第一声是什么歌?..老歌
早恋的意思是好多岁以下搞恋爱的人。一个人的
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?