Huffman编码
代码
#include "stdafx.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MIN 1000
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
void Select(HuffmanTree HT,int i, int &s1, int &s2)
{
int j;
int min=MIN;
for(j=1;j<i;j++)
{
if(HT[j].weight<=min&&HT[j].parent==0)
{ min=HT[j].weight;
s1=j;
}
}
min=MIN;
for(j=1;j<i;j++)
{
if((HT[j].weight<=min)&&(j!=s1)&&HT[j].parent==0)
{
min=HT[j].weight;
s2=j;
}
}
}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC, int *w, int n)
{
int m,i,s1=1,s2=1,f,c,start;
char *cd;
HuffmanTree p;
if(n<=1) return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0号单元未用
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
//*p={*w,0,0,0};
p->weight=*w; //******************这里注意赋值的格式
(*p).parent=0; //******************如果采用这种格式是错误的: *p.parent=0
(*p).lchild=0;
(*p).rchild=0;
printf("the weight of HT[%d] is %d\n",i,HT[i].weight);
}
for(;i<=m;++i)
{
//*p={0,0,0,0};
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
}
for(i=n+1;i<=m;++i)
{
Select(HT,i-1,s1,s2);
printf("s1=%d,s2=%d\n",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;
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char)); //这里开辟一个较大的空间,因为长度不可能超过n
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(HC[i],&cd[start]); //巧妙之处:这里从cd数组的中间已经编码的元素开始拷贝
}
free(cd);
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MIN 1000
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
void Select(HuffmanTree HT,int i, int &s1, int &s2)
{
int j;
int min=MIN;
for(j=1;j<i;j++)
{
if(HT[j].weight<=min&&HT[j].parent==0)
{ min=HT[j].weight;
s1=j;
}
}
min=MIN;
for(j=1;j<i;j++)
{
if((HT[j].weight<=min)&&(j!=s1)&&HT[j].parent==0)
{
min=HT[j].weight;
s2=j;
}
}
}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC, int *w, int n)
{
int m,i,s1=1,s2=1,f,c,start;
char *cd;
HuffmanTree p;
if(n<=1) return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0号单元未用
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
//*p={*w,0,0,0};
p->weight=*w; //******************这里注意赋值的格式
(*p).parent=0; //******************如果采用这种格式是错误的: *p.parent=0
(*p).lchild=0;
(*p).rchild=0;
printf("the weight of HT[%d] is %d\n",i,HT[i].weight);
}
for(;i<=m;++i)
{
//*p={0,0,0,0};
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
}
for(i=n+1;i<=m;++i)
{
Select(HT,i-1,s1,s2);
printf("s1=%d,s2=%d\n",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;
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
cd=(char*)malloc(n*sizeof(char)); //这里开辟一个较大的空间,因为长度不可能超过n
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(HC[i],&cd[start]); //巧妙之处:这里从cd数组的中间已经编码的元素开始拷贝
}
free(cd);
}
int _tmain(int argc, _TCHAR* argv[])
{
HuffmanTree HT;
HuffmanCode HC;
int w[5]={1,2,3,4,5};
int n=5,i;
HuffmanCoding(HT,HC,w,n);
for(i=1;i<=n;i++)
printf("the i node coding is %s\n",HC[i]);
while(1);
return 0;
}