赫夫曼编码
已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试编写算法求其赫夫曼编码
1 #include<iostream> 2 using namespace std; 3 //#include "HTNode.h" 4 typedef char **HuffmanCode; 5 typedef struct 6 { 7 int weight; 8 int parent,lchild,rchild; 9 }HTNode,*HuffmanTree;
void Select(HuffmanTree &HT,int n,int &s1,int &s2) { int i; int min=0; for(i=1;i<=n;++i) { if(HT[i].parent==0) { if(min==0) { min=HT[i].weight;min++;s1=i; } if(HT[i].weight<min) { min=HT[i].weight;s1=i; } } } min=0; for(i=1;i<=n;++i) { if((HT[i].parent==0)&&(i!=s1)) { if(min==0) {min=HT[i].weight;min++;s2=i;} if(HT[i].weight<min) {min=HT[i].weight;s2=i;} } } if(s2<s1) //保证s1的下标值小与s2实现左右子树的大小对称 { s1=s1+s2; s2=s1-s2; s1=s1-s2; } } void CreatHuffmanTree(HuffmanTree &HT,int n) { //构造赫夫曼树 int i,m,s1,s2; if(n<=1)return; m=2*n-1; HT=new HTNode[m+1];//树的信息储存在数组中 for(i=1;i<=m;++i) { HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } cout<<"请输入8个权值:\n"; for(i=1;i<=n;++i) cin>>HT[i].weight;//输入树叶子结点的权值 for(i=n+1;i<=m;++i) { //在HT数组中选择两个其双亲域为0且权值最小的结点,并返回它们的下标S1,S2 Select(HT,i-1,s1,s2); cout<<"s1="<<s1<<"s2="<<s2<<endl; 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 CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n) { int start,i,c,f; HC=new char*[n+1]; char *cd=new char[n]; cd[n-1]='\0'; for(i=1;i<=n;++i) { start=n-1; c=i;f=HT[i].parent; while(f!=0) { --start; if(HT[f].lchild==c) cd[start]='0'; else cd[start]='1'; c=f;f=HT[f].parent; } HC[i]=new char[n-start]; strcpy(HC[i],&cd[start]); } delete cd; }
int main() { HuffmanTree HT; HuffmanCode HC; int i,n=8; CreatHuffmanTree(HT,n); CreatHuffmanCode(HT,HC,n); for(i=1;i<=n;i++) cout<<"第"<<i<<"个字符的编码"<<HC[i]<<endl; return 0; }
/*
请输入8个权值:
5 29 7 8 14 23 3 11
s1=1 s2=7
s1=3 s2=4
s1=8 s2=9
s1=5 s2=10
s1=6 s2=11
s1=2 s2=12
s1=13 s2=14
第1个字符的编码0110
第2个字符的编码10
第3个字符的编码1110
第4个字符的编码1111
第5个字符的编码110
第6个字符的编码00
第7个字符的编码0111
第8个字符的编码010
Press any key to continue
*/
每一成功的背后都有个人的努力和家人的支持