基本概念
1、结点的路径长度:两结点间间路径上的分支数
2、树的路径长度:从根结点到每一个结点的路径长度之和
3、结点的带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积
4、树的带权路径长度:树中所有叶子结点的带权路径长度之和
构造哈夫曼树(贪心算法)
权值越大的叶子离根越近
具有相同带权节点的哈夫曼树是不唯一的
构造森林全是根(每个每个带权值结点都做根,造成结点个数的森林)
选用两小造新树(选出两个权值小的树作为左右子树构造一个新的树)
删除两小填新人(新树的权值是“两小”权值相加)
重复2、3剩单根(重复2.3步骤,直到剩下一个根)
哈夫曼树的结点的度数为0或2,没有度为1的结点
包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个度为二的新结点,故总结点为2n-1;
算法实现
(顺序存储结构---一维数组)
//结点类型定义 typedef struct{ int weight; //权值 int parent,lch,rch; }HTNode,*HuffmanTree; void CreatHuffmanTree(HuffmanTree HT,int n){ if(n<=1) return ; m=2*n-1; //生成树共有m个结点 HT=new HTNode[m+1]; //0号元素不使用 for(int i=1;i<=m;++i){ HT[i].lch=0;HT[i].rch=0;HT.[i].parent=0; } for(int i=1;i<=n;++i){ scanf("%d",&HT[i].weight); } for(i=n+1;i<=m;i++){ select(HT,i-1,s1,s2);//在HT[k](1<=k<=i-1)中找出最小的两个双亲为零且权值最小的结点返回他们在HT中的序号s1,s2 HT[s1].parent=i;HT[s2].parent=i; //表示从表中删除是s1,s2 HT[i].ch=s1;HT[i].rch=s2; //s1,s2分别作为i的左右孩子 HT[i].weight=HT[s1].weight+HT[s2].weight; //i的权值为左右孩子之和 } }
应用(哈夫曼编码)
、算法实现