建立Huffman Tree的过程: 1.一共有n个权值,看成n个只有根节点的树,
2.选择其中最小的两个树,构建出一个新树,根节点为两树根节点的权值之和,这两个树为新树的左右子树。
3.删除原来的两个树,将新树加入集合,重复操作,直至只有一个树为止。
我们要知道一个知识点,对于n个叶子节点的树,共有2n-1个节点。
/********************************/
/* Huffman Tree */
/* zengxing */
/* 12/4/18 */
/********************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct tNode{
int weight;
int parent,lchild,rchild;
/* tNode(){
weight = 0;
parent = 0;
lchild = 0;
rchild = 0;
}
*/
}htNode,*pHuffNode;
typedef char **HuffmanCode; //每个节点的编码
static void Select(const pHuffNode HT,const int count,int &s1,int &s2);
static void HuffmanCoding(pHuffNode &HT,HuffmanCode &HC,int *w,int n);
/*************************************************/
/* 功能:HuffmanTree的建立 */
/* 参数:树,编码,权值,元素个数 */
/*************************************************/
void HuffmanCoding(pHuffNode &HT,HuffmanCode &HC,int *w,int n)
{
if(n<1) return ;
int m = 2*n -1,i;
//开辟节点空间
HT = (pHuffNode)malloc((m+1)*sizeof(htNode));
for(i=1;i<=n;i++) //给每个叶子节点赋权值
{
HT[i].weight = w[i];
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for(;i<=m;i++)
{
HT[i].weight = 0;
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for(i=n+1;i<=m;i++) //根据定义建立Huffmantree
{
int s1=0,s2=0;
Select(HT,i-1,s1,s2); //查找到两个节点权值最小
if(!(s1&&s2)) printf("Error\n");
else{ //开始构造新的节点
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 *)); //每个节点编码指针
char *ch=(char *)malloc(n*sizeof(char)); //每个编码空间
ch[n-1] = '\0';
for(i=1;i<=n;i++)
{
int start = n-1;
int f = HT[i].parent; //待编码节点父节点
int c = i; //本节点
while(f){ //非根节点
if(HT[f].lchild == c) ch[--start] = '0';
else ch[--start] = '1';
c = f;
f = HT[f].parent;
}
HC[i] = (char *)malloc((n-start)*sizeof(char));
strcpy(HC[i],&ch[start]);
}
free(ch);
}
/*************************************************/
/* 功能:找出权最小的两个节点 */
/* 参数:树,查找范围,节点标号 */
/*************************************************/
void Select(const pHuffNode HT,const int count,int &s1,int &s2)
{
int min = 10000,i,j;
// int s1temp,s2temp;
for(i=1;i<count;i++){
if(HT[i].parent) continue;
for(j=i+1;j<=count;j++){
if(HT[j].parent) continue;
if(min > (HT[i].weight+HT[j].weight))
{
min = HT[i].weight+HT[j].weight;
s1 = i;
s2 = j;
}
}
}
}
int main()
{
pHuffNode huffTree = NULL;
HuffmanCode huffCode =NULL;
int weight[9]={0,5,29,7,8,14,23,3,11};
int i;
HuffmanCoding(huffTree,huffCode,weight,8);
for(i = 1;i<=8;i++)
printf("%s\n",huffCode[i]);
system("pause");
}
赫夫曼树
最新推荐文章于 2022-02-25 21:57:21 发布