其他分享
首页 > 其他分享> > 找出段落中每个字母 构造哈夫曼树

找出段落中每个字母 构造哈夫曼树

作者:互联网

过程

算出字母的频率

计算出每个英文字母出现的概率,无论大小写,忽略其他字符。并以概率作为权重。

构造哈夫曼树

根据哈夫曼树构造原理构造出哈夫曼树:规定小的结点在左边,大的在右边。左边的编码为‘0’,右边的编码为‘1’。
哈夫曼树

代码以及结果

代码

#include <stdio.h>
#include <stdlib.h>
#define MAXBIT  50
#define MAXLEAF 50
#define MAXNODE 2 * MAXLEAF - 1
#define INFINITY 65535

//编码结构体
typedef struct HCodeType{
	int start;
	int bit[MAXBIT];
}HCodeType;

//结点结构体
typedef struct HNode{
	int parent, lchild, rchild;
	double weight;
	char data;
}HNode;

//构造哈夫曼树 
void HuffmanTree(HNode HN[MAXNODE], int n){
	int i = 0, j;
	int x1, x2;
	double s1, s2;
	char ch;
	
	printf("请输入各种字母\n");
	//初始化哈夫曼树的叶子结点 
	while(i < n){
		HN[i].parent = -1;
		HN[i].lchild = -1;
		HN[i].rchild = -1;
		HN[i].weight = 0;
		scanf("%c", &ch);
		scanf("%c", &HN[i].data);
		i++;
	}
	
	printf("请依次输入字母的权重\n");
	i = 0;
	while(i < n){
		scanf("%lf", &HN[i].weight);
		i++;
	} 
	
	//初始化哈夫曼树中其他结点 
	for(i = n; i < 2 * n - 1; i++){
		HN[i].parent = -1;
		HN[i].lchild = -1;
		HN[i].rchild = -1;
		HN[i].weight = 0;
		HN[i].data = '0';
	}
	
	//选出最小权重的两个结点 
	for(i = 0; i < n - 1; i++){
		s1 = s2 = INFINITY;
		x1 = x2 = 0;
		
		for(j = 0; j < n + i; j++){
			if(HN[j].weight < s1 && -1 == HN[j].parent){
				s2 = s1;
				x2 = x1;
				s1 = HN[i].weight;
				x1 = j;
			}else if(HN[j].weight < s2 && -1 == HN[j].parent){
				s2 = HN[j].weight;
				x2 = j;
			}
		}
		HN[x1].parent = n + i;
		HN[x2].parent = n + i;
		HN[n + i].weight = HN[x1].weight + HN[x2].weight;
		HN[n + i].lchild = x1;
		HN[n + i].rchild = x2;
	}
}

int main(){
	HNode HN[MAXNODE];
	HCodeType HC[MAXLEAF], cd;
	int i, j, k, p;
	int n;
	printf("请输入字母的总数\n");
	scanf("%d", &n);
	HuffmanTree(HN, n);
	
	//自下而上获取编码,逆序存入
	for(i = 0 ; i < n; i++){
		cd.start = n - 1;
		k = i;
		p = HN[k].parent;
		while(p != -1){
			if(k == HN[p].lchild){
				cd.bit[cd.start] = 0;
			}else{
				cd.bit[cd.start] = 1;
			}
			cd.start--;
			k = p;
			p = HN[k].parent; 
		}
		
		for(j = cd.start + 1; j < n; j++){
			HC[i].bit[j] = cd.bit[j];
			HC[i].start = cd.start;
		}
	}
	
	//输出编码
	for(i = 0; i < n; i++){
		printf("%c  ", HN[i].data);
		for(j = HC[i].start + 1; j < n; j++){
			printf("%d", HC[i].bit[j]);
		}
		printf("\n");
	} 
	
	return 0;
}

运行结果

结果

标签:段落,map,哈夫曼,weight,++,字母,cd,HN
来源: https://blog.csdn.net/triggerV/article/details/118106224