哈夫曼树的创建

哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。

 

代码实现:

#include<stdio.h> 
#include<stdlib.h>
typedef struct node{
	char word;
	int weight;
	struct node *left;
	struct node *right;
}HuffNode;


//创建哈夫曼树 
HuffNode* CreateHuffmantree(HuffNode** F,int n){
	int i,loop,k1,k2;    //k1存放最小值,k2存放次小值
	HuffNode *pa;
	for(loop=1;loop<n;loop++){
		for(k1=0;k1<n&&!F[k1];k1++);   //遍历森林找到第一个非空的树 
		for(k2=k1+1;k2<n&&!F[k2];k2++);  //遍历森林找到第二个非空的树 
		for(i=k2;i<n;i++){        //寻找weight值最小和次小的两棵树,k1为最小下标,k2为次小的下标 
			if(F[i]){
				if(F[i]->weight<F[k1]->weight){
					k2=k1;
					k1=i;
				}else if(F[i]->weight<F[k2]->weight){
					k2=i;
				}
			}
		}
		pa=(HuffNode*)malloc(sizeof(HuffNode));   //创建结点,把F[k1]和F[k2]挂到pa上 
		pa->weight=F[k1]->weight+F[k2]->weight;
		pa->word='X';
		pa->left=F[k1];
		pa->right=F[k2];
		F[k1]=pa;
		F[k2]=NULL;  
	}
	return F[k1];
}


 //前序遍历输出哈夫曼树 
void PrintLink(HuffNode* root){
	if(root){
		printf("%c %d  ",root->word,root->weight);
		PrintLink(root->left);
		PrintLink(root->right);
	}
}


int main(void){
	HuffNode *root;
 	int n;
 	printf("请输入需要传输不同字符的个数:\n");
	scanf("%d",&n);
	fflush(stdin);
	HuffNode** F;
	F=(HuffNode**)malloc(n*sizeof(HuffNode*));
	for(int i=0;i<n;i++){
		F[i]=(HuffNode*)malloc(sizeof(HuffNode));
		F[i]->left=F[i]->right=NULL;
		printf("请输入传输的字符:");	
		scanf("%c",&F[i]->word);
		fflush(stdin);
		printf("请输入传输的频率:");
		scanf("%d",&F[i]->weight);
		fflush(stdin);
	}

	root=CreateHuffmantree(F,n);   //创建哈夫曼树 
	
	PrintLink(root);     //前序遍历输出哈夫曼树 
}

 

运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值