哈夫曼数的构建,编码代码

#include<bits_stdc++.h>
using namespace std;
typedef struct //huffmantree node
{
int w;
int p,lc,rc;
}hmnode,hftree;
typedef char **hfcode;//编码表
void tsort(hftree t[],int n,int &s1,int &s2)
{
int h,j;//提出变量
for(h=0;h<n;h++)
if(t[h].p==0)
{s1=h;break;}
for(j=h+1;j<n;j++)
if(t[j].p==0&&t[j].w<t[s1].w)
s1=j;
for(h=0;h<n;h++)
if(t[h].p==0&&h!=s1)
{s2=h;break;}
for(j=h+1;j<n;j++)
if(t[j].p==0&&t[j].w<t[s2].w&&j!=s1)//j!=s
s2=j;
}
void savetree(hftree t[],int n)//save huffmantree
{
int m=2*n-1;
ofstream pout("hfmtree.txt");
if(!t)
return;
for(int i=0;i<m;i++)
{
pout<<t[i].w<<endl;
}
}
void inithfmtree(hftree t[],int *w,int n)//initialize huffmantree
{
for(int i=0;i<n;i++)
{
t[i].w=w[i];
t[i].p=0;//可以=child
t[i].lc=t[i].rc=-1;//不能=0,第一个元素也为零,循环会无限进行
}
for(i=n;i<2*n-1;i++)
{
t[i].w=0;
t[i].p=0;
}
}
void creathf(hftree t[],hfcode &hc,int n)//creat
{
int s1=0,s2=0,a=0,i;
for(i=n;i<2*n-1;i++)
{
tsort(t,n+a,s1,s2);
t[s1].p=i;
t[s2].p=i;
t[i].lc=s1;
t[i].rc=s2;
t[i].w=t[s1].w+t[s2].w;a++;
}//构建huffman tree
savetree(t,n);
hc=(hfcode)malloc(n*sizeof(char *));
char *cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
int s,c,k;
for(i=0;i<n;i++)
{
s=n-1;
for(c=i,k=t[i].p;k!=0;c=k,k=t[k].p)//int c=i,k=t;k前不需要再加int!
{
if(t[k].lc==c) cd[--s]='0';//逆求
else cd[--s]='1';
}
hc[i]=(char *)malloc((n-s)*sizeof(char));//开创n-s,记录
strcpy(hc[i],cd+s);//strcpy用法!!

}
}
void encode(hfcode &hc,char *ch,int n)//code
{
cout<<"文件内容为:"<<endl;
char c;
char f[100];
int a=0;
fstream in;
in.open("tobetran.txt",ios::in);//文件操作,fstream in ;in.open(,)
while((c=in.get())!=EOF)
{
f[a]=c;a+=1;
cout<<c;
}
in.close();
cout<<endl<<"编码后为:"<<endl;
ofstream out("codefile.txt");
for(int i=0;i<a;i++)
{
for(int j=0;j<n;j++)//二重循环对比f,ch
{
if(f[i]==ch[j])
{
cout<<hc[j];
out<<hc[j];
}
}
}
cout<<endl;
out.close();
}
void decodeing(hftree t[],int n,char *ch)//decode
{
cout<<"文件内编码:"<<endl;
char c;
char p[100];
int m=2*n-2;//数组从0开始,-2!
int a=0;
fstream in;
in.open("codefile.txt",ios::in);
while((c=in.get())!=EOF)
{
cout<<c;
p[a]=c;
a++;
}
in.close();
p[a]='$';// end-mark
cout<<endl<<"译码:"<<endl;
fstream out("textfile.txt");
int i;
for(i=0;p[i]!='$';i++)//i++就可以
{
if(p[i]=='0')
{
m=t[m].lc;
}
else if(p[i]=='1')
{
m=t[m].rc;
}
if(t[m].lc==-1&&t[m].rc==-1)
{
cout<<ch[m];
out<<ch[m];//input to file
m=2*n-2;//返回根节点
}
}
out.close();
}
void print()//print the code
{
fstream in,pout;
in.open("codefile.txt",ios::in);
pout.open("codeprint.txt",ios::out);
int ct=0;
char c;
while((c=in.get())!=EOF)
{
cout<<c;
pout<<c;
ct++;
if(ct%50==0)
{
pout<<endl;
}
}
in.close();//close the file
pout.close();
}
void treeprint()//print the tree
{
fstream pout,in;
pout.open("treeprint.txt",ios::out);
in.open("hfmtree.txt",ios::in);
char c;
cout<<endl<<"打印树:"<<endl;
while((c=in.get())!=EOF)
{
cout<<c;
pout<<c;
}
in.close();
pout.close();
}
int main()
{
int n;
cout<<"请输入字符个数:"<<endl;
cin>>n;
int *w;
char *ch;
w=(int*)malloc(n*sizeof(int));
ch=(char*)malloc(n*sizeof(char));
cout<<"请输入字符及权值:"<<endl;
for(int i=0;i<n;i++)
{
cout<<"char:"<<endl;
cin>>ch[i];
cout<<"weight:"<<endl;
cin>>w[i];
}
hftree t[20];//结构体数组
hfcode hc;//char **hc
inithfmtree(t,w,n);
creathf(t,hc,n);
encode(hc,ch,n);
decodeing(t,n,ch);
print();
treeprint();
return 0;
}//指针、malloc、函数传递

posted @ 2018-02-12 09:20  夜游星  阅读(347)  评论(0编辑  收藏  举报