#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
int weight;
int parent, lchild,rchild;
}HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n); //w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC
void select(const HuffmanTree &HT, int n, int &s1, int &s2); //选择parent为0且weiht最小的两个结点,其序号分别为s1,s2
int main(){
HuffmanTree HT;
HuffmanCode HC;
int i;
const int n = 8;
int weight[n] = {5,29,7,8,14,23,3,11};
HuffmanCoding(HT, HC, weight, n);
for(i=1; i<=n; i++)
printf("%d %s\n",HT[i].weight, HC[i]);
return 0;
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){ //w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC
int i,m,s1,s2;
// HuffmanTree p;
int start,f,c;//start指向当前编码位置,f为parent结点序号,c为当前的结点序号
if(n <= 1) return ;
m = 2*n-1;
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); //0号单元未用
memset(HT,0,(m+1)*sizeof(HTNode));
for(i=1; i<=n; ++i, ++w) HT[i].weight = *w;
for(i = n+1; i<=m; i++){ //建赫夫曼树
select(HT, i-1, s1, s2);
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;
}
//求赫夫曼编码
HC = (HuffmanCode)malloc((n+1) * sizeof(char *)); //分配n个字符编码的头指针向量
char *cd = (char *)malloc(n * sizeof(char)); //分配求编码的工作空间
cd[n-1] = '\0';//编码结束符
for(i=1; i<=n; i++){ //逐个字符求赫夫曼编码
start = n-1;//编码结束符位置
for(c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent) //从叶子到根你想求编码
if(HT[f].lchild == c) cd[--start] = '0';
else cd[--start] = '1';
HC[i] = (char *)malloc((n-start) * sizeof(char)); //为第i个字符编码分配空间
strcpy(HC[i], &cd[start]); //从cd复制编码到HC
}
free(cd);
}
void select(const HuffmanTree &HT, int n, int &s1, int &s2){ //选择parent为0且weiht最小的两个结点,其序号分别为s1,s2
if(n < 1) return ;
int i,min1,min2; //min1为最小,min2为第二小
int ic=0; //主要用来处理初始时的情况 和 当!=0 的数仅剩2个的情况
for(i=1; i<=n; i++){
if(HT[i].parent != 0) continue;
if(ic == 0){
min1 = i; min2 = i; ic++;
}
else if(ic == 1){
if(HT[min1].weight > HT[i].weight){
min2 = min1; min1 = i; ic++;
}
else{
min2 = i; ic++;
}
}
else{
if(HT[min1].weight > HT[i].weight){
min2 = min1;
min1 = i;
}
else if(HT[min2].weight > HT[i].weight) min2= i;
else if(HT[min2].weight == HT[i].weight && min1 == min2) min2 = i;
}
}
s1 = min1; s2 = min2;
}
赫夫曼树
最新推荐文章于 2018-06-17 11:42:30 发布