huffman编码

来源:互联网 发布:单片机接口第2版张毅刚 编辑:程序博客网 时间:2024/03/29 03:02

//输入一串字符,统计各个字符的频数,然后进行huffman编码,最后输出编码结果
//由于采用数组静态存储,最多只能输入100个字符
//2007年12月1日21:00
//运行环境:visual c++ 6.0
#include<iostream>
#include<string>
using namespace std;
struct Huffman
{
 int value;
 int lchild;
 int rchild;
 int parent;
};
int n=100;
int m=199;//2*n-1
Huffman huffman[199];
int curmin1,curmin2;  //当前权值最小的两个根节点
string code[100];    //编码
//////////////////////////////////////////////////////////////////////////
char c[100];     //存储已经识别的字符
char ch;        //当前字符
int top=-1;     //C的顶部指针
int num[100];    //存放字符个数
int length=-1;   //输入的字符长度
char input[100];    //输入的字符
int count=0;       //不重复的字符的个数
int includes(char ch) //判断当前字符是否包含在已经识别的字符中
{
 for(int i=0;i<=top;i++)
  if(c[i]==ch)   
   return i;
 return -1;
}
void frequency(char *s)  //计算频率
{
 for(int j=0;j<=length;j++)
 {
  ch=s[j];  
  int i=includes(ch);
  if(i==-1)     //不存在
  {
   top++;
   c[top]=ch;  
   num[top]=1; 
   count++;
  }
  else         //已经存在
   num[i]++;
 }
}
void outputfrequency()  //输出输入字符的频数
{
 for(int i=0;i<count;i++)
 {
  cout<<c[i]<<"  "<<num[i]<<endl;
 }
}
//////////////////////////////////////////////////////
void init()   //初始化
{
 for(int i=0;i<m;i++)
 {
  huffman[i].value=0;
  huffman[i].parent=0;
  huffman[i].lchild=0;
  huffman[i].rchild=0;
 }
 for(int j=0;j<count;j++)
 {
    huffman[j].value=num[j];    //把count个字符的权值赋给树中的根接点
 }
}
void selectmin()
{//的到两个权值最小的接点
 int tempvalue1=100;
 int tempvalue2=100;
 for(int i=0;i<m;i++)
 {
  if(huffman[i].parent==0&&huffman[i].value!=0)
  if(huffman[i].value<tempvalue1)
  {
   tempvalue1=huffman[i].value;
   curmin1=i;
  }
 }
 for(int j=0;j<m;j++)
 {
  if(j!=curmin1)
  if(huffman[j].parent==0&&huffman[j].value!=0)
  if(huffman[j].value<tempvalue2)
  {
   tempvalue2=huffman[j].value;
   curmin2=j;
  }
 }
}
void createhuffmantree()
{//创建HUFFMAN树
 for(int i=count;i<2*count-1;i++)
 {
  selectmin();
  huffman[curmin1].parent=i;
  huffman[curmin2].parent=i;
  huffman[i].lchild=curmin1;
  huffman[i].rchild=curmin2;
  huffman[i].value=huffman[curmin1].value+huffman[curmin2].value;
 }
}
void huffcode()
{//得到接点的编码
 int c,p;
 for(int i=0;i<count;i++)
 {
  c=i;
  p=huffman[c].parent;
  while(p!=0)
  {
   if(c==huffman[p].lchild)//如果是左孩子,就编码为零
    code[i]='0'+code[i];
   else
       code[i]='1'+code[i];//否则编码为1
   c=p;
   p=huffman[c].parent;
  }
 }
}
void outputresult()        //输出编码结果
{
    for(int i=0;i<count;i++)
  cout<<c[i]<<"  "<<code[i]<<endl;
}
void main()
{
 cout<<"请输入字符串,输入0结束:"<<endl;
 char tempch;
 cin>>tempch;
 while(tempch!='0')//输入0时结束输入
 {
   input[++length]=tempch;
   cin>>tempch;
 }
 cout<<endl;
 frequency(input);
 cout<<"字符与频数:"<<endl;
 outputfrequency();
 //////////////////////////////////////////////////////////////////////////////////
 init();
 createhuffmantree();
 huffcode();
 cout<<"编码结果:"<<endl;
 outputresult();
}

 

原创粉丝点击