树与二叉树
哈夫曼树及其实现
引入
- 判断树
基本概念
- 路径长度
定义
- 满二叉树不一定是二叉树
- 哈夫曼树中权越大离根越近
- 具有相同带权结点的哈夫曼树不唯一
哈夫曼树的构造算法
- 贪心算法:构造哈夫曼树首先选择权小的叶子结点
- 哈夫曼树的结点度数为0/2,没有度为1的结点
- 含n个叶子结点的哈夫曼树共有2n-1个结点(进行n-1次合并,共产生n-1个新节点)
算法实现
- 采用顺序储存
typedef struct{
int weight;
int parent,lch,rch;
}HTNode,*HuffmanTree;//结点类型
void CreatHuffmanTree(HuffmanTree HT,int n){
// init
if(n<=1)return;
int m=2*n-1;
HT = new HTNode[m+1];
for(int i=1;i<=m+1;i++){
HT[i].lch=0;
HT[i].rch=0;
HT[i].parent=0;
}
for(int i=1;i<=n;i++){
cin>>HT[i].weight;
}
int s1,s2;
for(int i=n+1;i<=m;i++){
Select(HT,i-1,s1,s2);
HT[s1].parent=i; HT[s2].parent=i;
HT[i].weight=HT[s1].weight+HT[s2].weight;
HT[i].lch=s1; HT[i].rch=s2;
}
}
void Select(HuffmanTree HT, int i,int &s1,int &s2){
s1=1;
s2=i;
for(int k=1;k<=i;k++){
if(HT[k].weight<HT[s1].weight && HT[k].parent==0){
s1=k;
}
}
for(int k=1;k<=i;k++){
if(HT[k].weight<HT[s2].weight && HT[k].parent==0&& k!=s1){
s2=k;
}
}
}
哈夫曼树的应用
哈夫曼编码
typedef char **HuffmanCode;
void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n){
HC = new char *[n+1];
char *cd = new char [n];
cd[n-1] = '/0';
for(int i=1;i<=n;i++){
int start = n-1;
int point = i;
int k = HT[i].parent;
while(k){
if(HT[k].lch==point)
cd[start] = '0';
else
cd[start] = '1';
point = k;k = HT[k].parent;
}
HC[i] = new char[n-start];
strcpy(HC[i],&cd[start]);
}
delete cd;
}