哈夫曼编码

#include<stdio.h>
#include<stdlib.h>
#include<String.h>

#define MAXLEN 100
#define MAX 100;

typedef struct node {
	int weight;
	int lchild;
	int rchild;
	int parent;
	char info;//每个节点的信息 
}hfNode;
/*
typedef   double   vector[100]; 
vector   arr;   ====> 等价于   double   arr[100];
*/
typedef hfNode hfm[MAXLEN];

int n;

/*初始化*/
void InitHfm(hfm hf) {
	int i;
	printf("输入n的值:");
	scanf("%d", &n);
	getchar();
	for(i=0; i<n; i++) {
		hf[i].weight = 0;
		hf[i].lchild = -1;
		hf[i].rchild = -1;
		hf[i].parent = -1;
	}
	printf("\n");
}

/*输入权值*/
void InputWeight(hfm hf) {
	int w, i;
	char inf;//
	for(i=0; i<n; i++) {
		printf("请输入第%d个字符:", i+1);
		scanf("%c", &inf);
		getchar();
		hf[i].info = inf;
		printf("请输入第%d个字符的权值:", i+1);
		scanf("%d", &w);
		getchar();
		hf[i].weight = w;
		printf("\n");
	}
}


/*找到两个权值最小的字符*/
void SelectMin(hfm hf, int i, int &p1, int &p2) {
	long min1 = MAX;
	long min2 = MAX;
	int j;
	for(j=0; j<i; j++) {//最小 
		if(hf[j].parent == -1) {
			if(min1>hf[j].weight) {
				min1 = hf[j].weight;
				p1 = j;
			}
		}
	}
	for(j=0; j<i; j++) {//次小 
		if(hf[j].parent == -1) { 
			if(min2>hf[j].weight && j!=p1) {
				min2 = hf[j].weight;
				p2 = j;
			}
		}
	}
} 

/*创建哈夫曼树*/
void CreatHfm(hfm hf) {
	int i, p1, p2;
	InitHfm(hf);
	InputWeight(hf); 
	for(i=n; i<2*n-1; i++) {
		SelectMin(hf, i, p1, p2);//找出两个权值最小的p1,p2 
		hf[p1].parent = i;//parent是编号 
		hf[p2].parent = i;
		hf[i].lchild = p1;
		hf[i].rchild = p2;
		hf[i].weight = hf[p1].weight + hf[p2].weight;
		hf[i].info = '0';
		hf[i].parent = -1;
	}
}

/*输出哈夫曼树*/
void PrintHfm(hfm hf) {
	int i;
	printf("\t\t权重\t父母\t左孩子\t右孩子\t字符\t\n");
	for(i=0; i<2*n-1; i++) {
		printf("\t\t%d\t%d\t%d\t%d\t%c\n", hf[i].weight, hf[i].parent, 
		hf[i].lchild, hf[i].rchild, hf[i].info);
	} 
	printf("\n\n");
} 


/*哈夫曼树路径递归算法*/
void HfmPath(hfm hf, int i, int j) {
	int a, b;
	a = i;
	b = j = hf[i].parent;
	if(hf[b].parent != -1) {
		i = j;
	 	HfmPath(hf, i, j);
	}
	if(hf[b].lchild == a) 
		printf("0");
	else 
		printf("1");	
} 


/*对字符进行初始编码*/
void HfmNode(hfm hf) {
	int i, j;
	
	for(i=0; i<n; i++) {
		j = 0;
		printf("\t\t%c\t%d\t", hf[i].info, hf[i].weight);
		HfmPath(hf, i, j);
		printf("\n");
	}
} 

/*对用户输入的电文进行编码*/
void EnCode(hfm hf) {
	char data[1000];
	int i, j;
	printf("\n\n请输入你要编码的字符:");
	gets(data);
	printf("编码结果为:");
	for(j=0; data[j]!='\0'; j++) {
		for(i=0; i<n; i++) {
			if(data[j]==hf[i].info)
				HfmPath(hf, i, j);
		}
	} 
} 

/*对用户输入的密文进行译码*/
void DeCode(hfm hf) {
	char data[100];
	int i, j, len;
	j = 2*n - 2;//j初始从树的根节点开始
	printf("\n\n请输入需要译码的字符串:");
	scanf("%s", data);
	len = strlen(data);
	printf("译码的结果为:");
	for(i=0; i<len; i++) {
		/*遇到0结束,然后j指向根节点,
		每次需从根节点找下来*/
		if(data[i] == '0') {
			j = hf[j].lchild;
			if(hf[j].lchild == -1) {
				printf("%c", hf[j].info);
				j = 2*n - 2;
			}
		}
		else if(data[i] == '1') {
			j = hf[j].rchild;
			/*当全为1时会执行下面的if*/ 
			if(hf[j].rchild == -1) {
				printf("%c", hf[j].info);
				j = 2*n - 2;
			}
		}
	}
	printf("\n"); 
}


main() {
	int i, j;
	hfm hf;
	CreatHfm(hf);
	PrintHfm(hf);
	HfmNode(hf);
	EnCode(hf);	
	DeCode(hf); 
}



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值