#include<iostream>
#include<stdlib.h>
#include<cstring>
using namespace std;
typedef struct hftree{
int might;
int parent,lch,rch;
char data;
}*tree,node;
typedef char** treecode;
int length;//字符串长度;
void select(tree T,int n,int &s1,int &s2)//找出权值最小的两个;
{
int k,m;
k=m=1000000;
for(int j=1;j<=n;j++)
{
if(m>T[j].might&&T[j].parent==0)
{
m=T[j].might;
s1=j;
}
}
for(int i=1;i<=n;i++)
{
if(i!=s1&&k>T[i].might&&T[i].parent==0)
{
k=T[i].might;
s2=i;
}
}
}
void hftree(tree &hf,int n)//创建霍夫曼树
{
int s1,s2;
if(n<=1) return;
int m=2*n-1;
for(int i=n+1;i<=m;++i)
{
select(hf,i-1,s1,s2);
hf[s1].parent=i;
hf[s2].parent=i;
if(s1<=s2){
hf[i].lch=s1;
hf[i].rch=s2;
}
else{
hf[i].lch=s2;
hf[i].rch=s1;
}
hf[i].might=hf[s1].might+hf[s2].might;
}
}
void codetree(tree hf,treecode &hc,int n)//获取字符的编码值
{
int m,p;
hc=new char*[n+1]; //指针数组;
char *cd=new char[n]; //存放编码
cd[n-1]='\0';
for(int i=1;i<=n;i++)
{
int start=n-1;
m=i;
p=hf[i].parent;
while(p!=0)
{
--start;
if(hf[p].lch==m)
{
cd[start]='0';
}
else
cd[start]='1';
m=p;
p=hf[p].parent;
}
hc[i]=new char[n-start];
strcpy(hc[i],&cd[start]);
}
delete []cd;
}
void input(tree &hf,int &n,char *date)//输入字符串
{
char *a=date;
int num[256]={0};
int b[256];
int c[256];
length=strlen(a);
for(int i=0;i<length;i++)
{
num[(int)a[i]]++;//统计每个字符的权值
}
n=0;
for(int i=0;i<256;i++)
{
if(num[i]!=0)
{
b[n]=num[i];
c[n]=(char)i;
++n;
}
}
hf=new node[2*n];
for(int i=1;i<=2*n-1;i++)
{
hf[i].data='\0';
hf[i].might=0;
hf[i].lch=0;
hf[i].rch=0;
hf[i].parent=0;
}
for(int i=1;i<=n;i++)
{
hf[i].might=b[i-1];
hf[i].data=c[i-1];
}
}
int weizhi(tree hf,char *q,int n)
{
char *date=q;
for(int j=1;j<=n;++j)
{
if(*date==hf[j].data)
return j;
}
}
void bianmachar(tree hf,char q[],treecode &hc,treecode &result,int n)//对字符串编码
{
char *date=q;
char *cd;
int m,p;
result=new char * [length+1];//存放每个字符的编码值;
hc=new char*[n+1];
cd=new char[n];
cd[n-1]='\0';
for(int i=0;i<length;++i)
{
m=weizhi(hf,&date[i],n);//获取每个字符在树中的位置
int start=n-1;
p=hf[m].parent;
while(p!=0)
{
--start;
if(hf[p].lch==m)
{
cd[start]='0';
}
else
cd[start]='1';
m=p;
p=hf[p].parent;
}
result[i+1]=new char[n-start];
strcpy(result[i+1],&cd[start]);
}
delete cd;
}
void chu(tree hf,treecode hc,treecode result,treecode hc1,int n)
{
int m=2*n-1;
// cout<<"每个字符在树中的位置"<<endl;
// for(int i=1;i<=m;i++)
// {
// cout<<i<<" "<<hf[i].data<<" "<<hf[i].might<<" "<<hf[i].parent<<" "<<hf[i].lch<<" "<<hf[i].rch<<endl;
// }
cout<<"每个字符的编码"<<endl;
for(int i=1;i<=n;i++)
{
cout<<hf[i].data<<" "<<hc1[i]<<endl;
}
cout<<"对字符串的编码"<<endl;
for(int j=1;j<=length;j++)
{
cout<<result[j];
}
}
int main()
{
char date[50];//字符串最大值为50;
tree hf;
treecode hc;
treecode hc1;
treecode result;
int n;
cout<<"输入字符串:";
gets(date);
input(hf,n,date);
hftree(hf,n);
codetree(hf,hc1,n);
bianmachar(hf,date,hc,result,n);
chu(hf,hc,result,hc1,n);
}
霍夫曼树编码实现
最新推荐文章于 2023-10-29 11:52:21 发布