huffman树的创建与编码

贴个代码,仅供参考。

      感觉三点比较重要:

1、熟悉指针、引用、内存分配。

2、清楚创建树与编码过程。该过程中有两点比较重要:a.创建叶子节点以外的节点时,是怎么select以及如何建立父子结点关系。b、在编码的时候是如何从叶子节点出发,一步一步查找的。

3、理解为何这样编码可以缩短编码长度。


#include<stdlib.h>
#include<cstring>
#include<iostream>
using namespace std;


#define MAXCODE   1000 //赫夫曼代码的最大长度
#define MAXWEIGHT 3000//定义最大权值


typedef struct {
  char c;
  unsigned int weight;
  unsigned int parent,lchild,rchild;
}HTnode,*HUffmantree;//动态分配数组储存赫夫曼编码表


typedef char ** HUffmancode;//动态储存和夫曼编码


void select(HUffmantree HT,int t,int &s1,int &s2)//select函数用于找出权值最小的两个结点
{


int i,m,n;
m=n=MAXWEIGHT;
for(i=1;i<=t;i++)
{
if(HT[i].parent==0 && (HT[i].weight<m || HT[i].weight<n))
        if(m<n)
{
n=HT[i].weight;  s2=i;  
}
else
{
m=HT[i].weight;
    s1=i;
}
}
if(s1>s2)
{
  i=s1;
  s1=s2;
  s2=i;
}
}


void HUffmanCreate(HUffmantree &HT,int n)
{
HUffmantree p;
int i,m;
int s1,s2;
if(n<=1)
return;


m=2*n-1;


HT=(HUffmantree)malloc((m+1)* sizeof(HTnode));


for(p = HT+1,i=1;i<=n;++i,++p)//初始化叶子节点。
{
cout<<"请输入第 "<<i<<" 个字符以及它的权重:"<<endl;
cin>>p->c>>p->weight;
p->lchild=0;
p->parent=0;
p->rchild=0;
}


for(;i<=m;++i,++p)//初始化叶子节点以外的的其他节点
{
p->weight=0;
p->lchild=0;
p->parent=0;
p->rchild=0;
}  


//创建赫夫曼树。


for(i=n+1;i<=m;++i)
{
  select(HT,i-1,s1,s2);
  HT[s1].parent=i;
  HT[s2].parent=i;
          HT[i].lchild=s1;
          HT[i].rchild=s2;
          HT[i].weight=HT[s1].weight + HT[s2].weight;


}
}


//从叶子节点到根逆向求每一个字符的赫夫曼码
void HUffmancoding(HUffmantree HT,HUffmancode &HC,int n)
{
   char *cd;
   int i,c,f,start;
   HC=(HUffmancode)malloc((n+1)*sizeof(char *));
   cd=(char *)malloc(n*sizeof(char));
   cd[n-1]='\0';


   for(i=1;i<=n;i++)
   {
     start=n-1;
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
{


if(HT[f].lchild == c)
cd [--start] = '0';
else
cd [--start] = '1';


HC[i] = (char *)malloc((n-start)*sizeof(char ));
strcpy_s(HC[i],n-start,&cd[start]);


}
   }
   free(cd);
}


int main()
{
HUffmantree hf;
HUffmancode hc;


int n,i;
cout<<"请输入字母数: ";
cin>>n;


HUffmanCreate(hf,n);
HUffmancoding(hf,hc,n);
    
cout<<"---------------------------------"<<endl;


       for(i=1;i<=n;i++)
        cout<<"字符:"<<hf[i].c<<"\t\t"<<"Huffmancode编码:"<<hc[i]<<endl;


cout<<"---------------------------------"<<endl;


 return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值