哈夫曼
来源:互联网 发布:vb.net 做app开发 编辑:程序博客网 时间:2024/05/02 19:02
#include<iostream.h>
#include<string.h>
#include<iomanip.h>
#include<fstream.h>
#include<stdlib.h>
const maxleaf=30;
const maxnode=maxleaf*2-1;
typedef struct //定义一个哈夫曼树的结构
{
char ch;
int weight;
int parent;
int lchild;
int rchild;
}HNodeType;
HNodeType hftree[maxnode+1];//定义一个哈夫曼树结构的数组
typedef struct //定义一个编码的结构
{
int bit[maxleaf+1];
int start;
}codetype;
codetype Huffcode[maxleaf];//定义一个编码的结构数组
void creathuffmantree(int n);//创建哈夫曼树
void huffcode(int n); //编码
void trancode(int n); // 译码
void printtree(int n); //打印哈夫曼树并输出屏幕中
int n;
void main()
{
int choice;
while(1)
{
cout<<" ★哈夫曼树的编码和译码★\n";
cout<<"请选择: "<<endl;
cout<<"1:创建哈夫曼树\n";
cout<<"2:编码\n";
cout<<"3:译码\n";
cout<<"4:打印哈夫曼树\n";
cout<<"5:退出\n";
cin>>choice;
switch(choice)
{
case 1:
{
cout<<"输入叶子结点数n:";
cin>>n;
cout<<""""<<endl;
creathuffmantree(n);
}break;
case 2: huffcode(n);break;
case 3: trancode(n);break;
case 4: printtree(n);break;
case 5: return;
}
}
}
void creathuffmantree(int n)
{
int i,j,x1,x2,m1,m2,c,p;
codetype cd;
for(i=0;i<maxleaf;i++)
{
hftree[i].parent=-1;
hftree[i].lchild=-1;
hftree[i].rchild=-1;
hftree[i].weight=-1;
}
cout<<"请输入字符和权值:\n"<<endl;
for(i=0;i<n;i++) //从键盘输入字符和权值
{
cout<<"输入第"<<i+1<<"个字符和权值: ";
cin>>hftree[i].ch;
cin>>hftree[i].weight;
}
for(i=0;i<n-1;i++) //构造哈夫曼树
{
m1=m2=10000;
x1=x2=0;
for(j=0;j<n+i;j++)
{
if(hftree[j].parent==-1&&hftree[j].weight<m1)
{
m2=m1;
x2=x1;
m1=hftree[j].weight;
x1=j;
}
else
if(hftree[j].parent==-1&&hftree[j].weight<m2)
{
m2=hftree[j].weight;
x2=j;
}
}
hftree[x1].parent=n+i;
hftree[x2].parent=n+i;
hftree[n+i].weight=hftree[x1].weight+hftree[x2].weight;
hftree[n+i].lchild=x1;
hftree[n+i].rchild=x2;
}
for(i=0;i<n;i++)
{
cd.start=n-1;
c=i;
p=hftree[c].parent;
while(p!=-1)
{
if(hftree[p].lchild==c)
cd.bit[cd.start]=0;
else cd.bit[cd.start]=1;
cd.start--;
c=p;
p=hftree[c].parent;
}
for(j=cd.start+1;j<n;j++)
Huffcode[i].bit[j]=cd.bit[j];
Huffcode[i].start=cd.start;
}
for(i=0;i<n;i++)
{
cout<<hftree[i].ch<<"的编码为: ";
for(j=Huffcode[i].start+1;j<n;j++)
cout<<Huffcode[i].bit[j];
cout<<endl;
}
}
void huffcode(int n) //编码
{
ofstream file1("e:\\hftreecode.txt",ios::out);
char ch;
int q=0;
int j;
cout<<"请输入要编码的字符串(按@)结束"<<endl;
cin>>ch; //对字符串进行编码
while(q<n&&ch!='@')
{
while(hftree[q].ch!=ch)
q++;
for(j=Huffcode[q].start+1;j<n;j++)
{
cout<<Huffcode[q].bit[j];
file1<<Huffcode[q].bit[j];
}
q=0;
cin>>ch;
}
file1.close();
cout<<endl;
}
void trancode(int n)//译码
{
char c;
int m1=0,m2=0;
ifstream file1("e:\\hftreecode.txt",ios::in);
while(file1.get(c)!='\0')
m1++;
file1.close();
if(m1==0)
{
cout<<"请先编码!!"<<endl;
return;
}
ifstream file2("e:\\hftreecode.txt",ios::in);
char *cc=new char[m1+1];
while(file2.get(c)!='\0')
{
cc[m2]=c;
m2++;
}
cc[m2]='\0';
int i,j=0;
i=2*n-2;
while(cc[j]!='\0')
{
if(cc[j]=='0')
i=hftree[i].lchild;
else
i=hftree[i].rchild;
if(hftree[i].lchild==-1)
{
cout<<hftree[i].ch;
i=2*n-2;
}
j++;
}
file2.close();
}
void printtree(int n)//打印哈夫曼树
{
int i;
ofstream file("e:\\printhuffman.txt",ios::out);
cout<<"字符"<<setw(8)<<"权值"<<setw(8)<<"左孩子"<<setw(8)<<"右孩子"<<setw(8)<<"双亲"<<endl;
file<<"字符"<<setw(8)<<"权值"<<setw(8)<<"左孩子"<<setw(8)<<"右孩子"<<setw(8)<<"双亲"<<endl;
for(i=0;i<2*n-1;i++)
{
cout<<hftree[i].ch<<setw(8)<<hftree[i].weight<<setw(8)<<hftree[i].lchild<<setw(8)<<hftree[i].rchild<<setw(8)<<hftree[i].parent<<endl;
file<<hftree[i].ch<<setw(8)<<hftree[i].weight<<setw(8)<<hftree[i].lchild<<setw(8)<<hftree[i].rchild<<setw(8)<<hftree[i].parent<<endl;
}
cout<<endl;
file.close();
}
- 哈夫曼
- 哈夫曼
- 哈夫曼
- 哈夫曼
- 哈夫曼算法
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼压缩
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 如何查看和修改Mac版本号
- Inductive hashing on Manifolds
- Ural-1297-Palindrome
- NAT四种类型和检测
- qsort与sort
- 哈夫曼
- 优秀的系统集成工程师应具备的技能
- win7 64位系统加载dsoframer.ocx问题解决方法
- MindManager安装
- 《月下独酌》 作者:李白
- Android源代码分析(二) MediaScanner源码分析(上)
- 银行家算法---C++实现
- The ``Clockwise/Spiral Rule''
- 数据库组合查询