#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
int *code;
char str;
}Num;
typedef struct
{
int weight,parent,left,right;
bool Selected; ///是否已经选过该节点,两个节点构建父节点时,选过的节点就不能再选了
Num ch;
}HNode,*pHNode;
const int n=5;
pHNode HTREE=NULL;
////哈夫曼树初始化,转载n个字符和相应的权值,并申请n-1个辅助节点用于构建Huffman树
void InitHtree(pHNode &htree,int n)
{
htree=(pHNode)malloc((2*n-1)*sizeof(HNode));
char str[]="abcde";
int weight[]={4,8,1,2,11};
for (int i=0;i<n;i++)
{
htree[i].weight=weight[i];
htree[i].left=-1;
htree[i].right=-1;
htree[i].ch.str=str[i];
htree[i].Selected=false;
}
}
////选取两个较小的节点,返回节点的序号
void SelectTwoMinNode(pHNode htree,int len,int &n1,int &n2)
{
int min1,min2;
int i,j;
for (i=0;i<len;i++)
{
if (htree[i].Selected==false)
{
min1=i;
}
}
for (j=0;j<len;j++)
{
if (htree[j].Selected==false&&j!=i-1)
{
min2=j;
}
}
if (htree[min1].weight>htree[min2].weight)
{
int temp=min1;
min1=min2;
min2=temp;
}
for (i=0;i<len;i++)
{
if (htree[i].Selected==false)
{
if (htree[i].weight<htree[min1].weight)
{
min2=min1;
min1=i;
}
else if(htree[i].weight<htree[min2].weight&&htree[i].weight>htree[min1].weight)
min2=i;
}
}
htree[min1].Selected=true;///标志已选取
htree[min2].Selected=true;
n1=min1;
n2=min2;
}
//////HuffmanTree讲的是如何编码,即构建字符和编码之间的对应关系
void HuffmanTree(pHNode &htree,int n)////htree是一个节点数组,n为字符个数
{
int m=2*n-1,n1,n2;
int i,child,parent;
int *path=(int *)malloc(m*sizeof(int));
for (i=n;i<m;i++)
{
SelectTwoMinNode(htree,i,n1,n2);
htree[i].left=n1;
htree[i].right=n2;
htree[n1].parent=htree[n2].parent=i;
htree[i].weight=htree[n1].weight+htree[n2].weight;
htree[i].Selected=false;
}
htree[--i].parent=-1;//根节点的标志
for (i=0;i<n;i++)
{
for (child=i,parent=htree[child].parent,m=0;parent!=-1;m++)
{
if (htree[parent].left==child)///孩子位于双亲的左边
path[m]=0;
else ///孩子位于双亲的右边
path[m]=1;
child=parent;
parent=htree[child].parent;
}
htree[i].ch.code=(int *)malloc(n*sizeof(int));
int k;
int len=m;
for (k=0;k<len;k++) /////倒序过来
htree[i].ch.code[k]=path[--m];
htree[i].ch.code[k]='\n';
}
delete[]path;
}
/////HuffmanCoding按照huffmantree对字符串编码
int *HuffmanCoding(pHNode htree,char * source)
{
int* encoding=new int[100];
int* p;
int len=strlen(source);
int pos;
int j=0;
for(int i=0;i<len;i++)
{
pos=*source++-'a';
p=htree[pos].ch.code;
while(*p!='\n')
encoding[j++]=*p++;
}
encoding[j]='\n';
return encoding;
}
/////对编码进行译码,还原字符
void HuffmanDecoding(pHNode htree,int m,int *buff)/////htree是一个节点数组,m为hree节点个数,buff字符串
{
int p=m-1;
while (*buff!='\n')
{
if (*buff==0)
p=htree[p].left;
else
p=htree[p].right;
buff++;
if (htree[p].left==-1&&htree[p].right==-1)
{
printf("%c",htree[p].ch.str);
p=m-1;
}
}
}
int main()
{
InitHtree(HTREE,n);
HuffmanTree(HTREE,n);
char *str="abcbcaedd";
int *result=HuffmanCoding(HTREE,str);
HuffmanDecoding(HTREE,2*n-1,result);
system("pause");
}
C++Huffman树的构造实现及编码译码过程
最新推荐文章于 2022-12-09 19:08:58 发布