哈夫曼编码还是在暑假时候看的,那时候并没有看懂因为比较菜(虽然现在也是很菜的),在《趣学算法》一书中这个问题讲解十分到位,我这篇博客真的是难以望其项背,只能对其进行一点借鉴和摘抄吧
哈夫曼编码是一棵树,权值越大的节点越靠近树根,越小的节点就越远离树根,从他的定义来看,首先想到的应该是贪心策略吧,没错就是贪心算法
虽然说是贪心算法,但是还要知道它 的实现方式啊,他的贪心策略是:每次从树的集合中取出没有双亲且权值最小的两棵树作为左右子树,并合并他们
步骤 :
1 :确定合适的数据结构(要知道他的左右子树,双亲,权值)
2:初始化,构造n颗节点为n的字符单节点树集合T={t1,t2,t3,t4···········tn},并且每棵树只有树根
3:如果集合中只剩下一棵树,那么哈夫曼树就构造成功,直接跳转到步骤6,否则就是从集合中继续拿出没有双亲的左右子树x,y,并将它们合并到一颗z树中,
z的权值为左右子树权值之和
4:从T集合中删除x,y 把新树z加入到集合T中
5:重复步骤3~4
6:约定左分支上的编码都是0,有分支上的编码都是1,从叶子节点开始逆序求出树的编码
图解:(这儿就直接调用这本书上的图片吧,是在太懒不想画图)
代码的实现:
#include<bits/stdc++.h> using namespace std; #define MAXBIT 100 #define MAXVALUE 10000 #define MAXLEAF 30 #define MAXNODE MAXLEAF*2-1 typedef struct{ double weight; int parent; int lchild; int rchild; char value; }HNodeType;//¶¨ÒåµÄÊǽڵã·Ö±ðÓÐȨÖØ£¬Ë«Ç׽ڵ㣬×óÓÒº¢×Ó£¬»¹Óдú±íµÄ×Ö·û typedef struct{ int bit[MAXBIT]; int start; }HCodeType;//ÕâÊDZàÂë½á¹¹Ìå HNodeType HuffNode[MAXNODE];//½Úµã½á¹¹ÌåÊý×é HCodeType HuffCode[MAXLEAF];//±àÂë½á¹¹ÌåÊý×é /*½ÓÏÂÀ´¿ªÊ¼¹¹Ôì¹þ·òÂüÊ÷*/ void HuffmanTree(HNodeType HuffNode[MAXNODE],int n) { /*i,jÊÇÑ»·±äÁ¿£¬m1,m2ÊÇ×îСµÄȨֵ x1,x2Êǹþ·òÂüÊ÷×îСȨֵ¶ÔÓ¦µÄÐòºÅ */ int i,j,x1,x2; double m1,m2; // ³õʼ»¯½Úµã for(i=0;i<2*n-1;i++) { HuffNode[i].lchild=-1; HuffNode[i].parent=-1; HuffNode[i].rchild=-1; HuffNode[i].weight=0; } for(i=0;i<n;i++) { cout<<"Please enter the value of every Node "<<i+1<<endl; cin>>HuffNode[i].value>>HuffNode[i].weight; } // ¹¹Ôì¹þ¸¥ÂüÊ÷ for(i=0;i<n-1;i++) {//Ҫѻ·n-1´Î m1=m2=MAXVALUE; x1=x2=0; //ÏÂÃ濪ʼÕÒ×îСµÄÁ½¸öÖµ for(j=0;j<n+i;j++) { if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1) { m2=m1; x2=x1; m1=HuffNode[j].weight; x1=j; } else if(HuffNode[j].weight<m2&&HuffNode[j].parent==-1) { m2=HuffNode[j].weight; x2=j; } } HuffNode[x1].parent=n+i; HuffNode[x2].parent=n+i; HuffNode[n+i].weight=m1+m2; HuffNode[n+i].lchild=x1; HuffNode[n+i].rchild=x2; cout<<"x1.weight and x2.weight in round "<<i+1<<"\t" <<HuffNode[x1].weight<<"\t"<<HuffNode[x2].weight<<endl;//ÓÃÓÚ²âÊÔ } } void HuffmanCode(HCodeType HuffCode[MAXLEAF],int n) { HCodeType cd; int i,j,c,p; for(i=0;i<n;i++) { cd.start=n-1; c=i; p=HuffNode[c].parent; while(p!=-1) { if(HuffNode[p].lchild==c) cd.bit[cd.start]=0; else cd.bit[cd.start]=1; cd.start--; c=p; p=HuffNode[c].parent; } for(j=cd.start+1;j<n;j++) HuffCode[i].bit[j]=cd.bit[j]; HuffCode[i].start=cd.start; } } int main() { int i,j,n; cout<<"Please enter n"<<endl; cin>>n; HuffmanTree(HuffNode,n); HuffmanCode(HuffCode,n); for(i=0;i<n;i++) { cout<<HuffNode[i].value<<": Huffman Code is: "; for(j=HuffCode[i].start+1;j<n;j++) { cout<<HuffCode[i].bit[j]; } cout<<endl; } return 0; }