求哈弗曼树的编码

Posted twinkle-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求哈弗曼树的编码相关的知识,希望对你有一定的参考价值。

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define N 20

#define M 2*N-1

typedef struct

//哈夫曼树的类型定义

{

int weight;

int parent;

int LChild;

int RChild;

}HTNode,HuffmanTree[M+1];

typedef char *HuffmanCode[N+1];

void CrtHuffmanTree(HuffmanTree ht,int w[],int n)//构造哈夫曼树ht[M+1],w[]存放n个权值

 

{

int i,k,Lnode,Rnode,Min1,Min2,max=0;

int m=2*n-1;

for(i=1;i<=n;i++) //叶子结点初始化

{

ht[i].weight=w[i];

ht[i].parent=0;

ht[i].LChild=0;

ht[i].RChild=0;

}

//ht[i]={ w[i],0,0,0};

for(i=n+1;i<=m;i++) //非叶子结点初始化

//ht[i]={0,0,0,0};

{

ht[i].weight=0;

ht[i].parent=0;

ht[i].LChild=0;

ht[i].RChild=0;

}

 

 

/*

 

for(i=1;i<=m;i++)

{

printf(" %d,",w[i]);

}

printf(" %n");

for(i=1;i<=m;i++)

{

printf(" %d,",ht[i].weight);

}

printf(" %d\n",max);

 

*/

 

 

 

for(i=n+1;i<=m;i++)//建立哈夫曼树

{

Min1=Min2=10000;

Lnode=Rnode=0;//Lnode存放最小值的位置,Rnode存放第二最小值的位置

for(k=1;k<i;k++)//只在尚未构造二叉树的结点中查找最小的两个结点

{

if(ht[k].parent==0)

{

if(ht[k].weight<Min1)//查找当前最小值

{

Min2=Min1;

Rnode=Lnode;

Min1=ht[k].weight;

Lnode=k;

}

else

if(k!=Lnode&&ht[k].weight<Min2)//查找当前第二最小值

{

Min2=ht[k].weight;

Rnode=k;

}

}

}

ht[i].weight=Min1+Min2;

ht[i].LChild=Lnode;ht[i].RChild=Rnode;

ht[Lnode].parent=i;ht[Rnode].parent=i;

}

printf("\n哈夫曼树的终态\n序号\tWeight\tParent\tLChild\tRChild\n");

for(i=1;i<=m;i++)//测试代码

{

printf("%d",i);

printf(" %d",ht[i].weight);

printf(" %d",ht[i].parent);

printf(" %d",ht[i].LChild);

printf(" %d",ht[i].RChild);

printf("\n");

}

printf("\n");

 

 

}

void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n)

//从叶子结点到根,逆求每个叶子结点对应的哈夫曼编码,左01

{

char *cd;

int i,j,c,p,start;

cd=(char *)malloc(n*sizeof(char));

cd[n-1]=‘\0‘;

for(i=1;i<=n;i++)

{

start=n-1;

c=i;p=ht[i].parent; //寻找该叶子结点的父母

while(p!=0)

{

--start;

if(ht[p].LChild==c)

cd[start]=‘0‘;//判断是左边还是右边

else

cd[start]=‘1‘;

c=p;p=ht[p].parent;//继续向上倒推

}

hc[i]=(char *)malloc((n-start)*sizeof(char));

//strcpy(hc[i],&cd[start]);

for(j=0;j<n-1;j++)

{

if(cd[j]==‘0‘||cd[j]==‘1‘)

printf("%c",cd[j]);

}

printf("\t");

for(j=0;j<n-1;j++)

{

cd[j]=‘ ‘;

}

}

free(cd);

}

void main()

{

HuffmanTree ht1;

HuffmanCode hc;

char ch[20];

int i,a,w[20];

printf("请输入字符个数(小于20):");

scanf("%d",&a);

printf("请输入字符:");

getchar();

for(i=1;i<=a;i++)

{

ch[i]=getchar();

}

getchar();

printf("请输入各个字符对应的权值:");

for(i=1;i<=a;i++)

{

scanf("%d",&w[i]);

}

CrtHuffmanTree(ht1,w,a);

printf("\n\t\ts对各字符的哈夫曼树编码\n");

printf("\t字符\t");

for(i=1;i<=a;i++)

{

printf("%c\t",ch[i]);

 

}

printf("\n\t权值\t");

for(i=1;i<=a;i++)

printf("%d\t",w[i]);

printf("\n  哈夫曼编码\t");

CrtHuffmanCode(ht1,hc,a);

printf("\n");

}

以上是关于求哈弗曼树的编码的主要内容,如果未能解决你的问题,请参考以下文章

Java---Huffman树的实现

哈弗曼树与哈夫曼编码

简单哈弗曼树(Java)

哈弗曼树及其操作

哈夫曼树及其编码

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树