哈夫曼树编码转换




#include<stdlib.h>
#include<stdio.h>
#include<String.h>
typedef struct{
	int weight;
	int parent;
	int left;
	int right;
}HuffmanTree;

typedef char *HuffmanCode;

void SelectNode(HuffmanTree *T, int n, int *bt1, int *bt2){
	int i;
	HuffmanTree *ht1, *ht2, *t;
	ht1 = ht2 = NULL;
	for(i = 1; i<=n; ++i){
		if(!T[i].parent){
			if(ht1 == NULL){
				ht1 = T + i;
				continue;
			}
			if(ht2 == NULL){
				ht2 = T + i;
				if(ht1 && ht2){
					if(T[i].weight <= ht1->weight){
						ht2 = ht1;
						ht1 = T + i;
					}else if(T[i].weight < ht2->weight){
						ht2= T + i;
					}
				}
			}
		}
	}
	
	if(ht1 > ht2){
		*bt2 = ht1 - T;
		*bt1 = ht2 - T;
	}else{
		*bt1 = ht1 - T;
		*bt2 = ht2 - T;
	}

}
void CreateTree(HuffmanTree *T, int n, int *w){
	int i, m = 2 * n - 1;
	int bt1, bt2;
	if(n<=1){
		return;
	}
	for(i = 1; i<=n; ++i){
		T[i].weight = w[i-1];
		T[i].parent = 0;
		T[i].left = 0;
		T[i].right = 0;
	}
	
	for(;i<=m;++i){
		T[i].weight = 0;
		T[i].parent = 0;
		T[i].left = 0;
		T[i].right = 0;
	}
	
	for(i=n+1;i<=m; i++){
		SelectNode(T, i - 1, &bt1, &bt2);
		T[bt1].parent = i;
		T[bt2].parent = i;
		T[i].left = bt1;
		T[i].right = bt2;
		T[i].weight = T[bt1].weight + T[bt2].weight;
	}
}
void HuffmanCodeing(HuffmanTree *ht, int n, HuffmanCode *hc){
	char *cd;
	int start, i;
	int current, parent;
	cd = (char *)malloc(sizeof(char) * n);
	cd[n-1] = '\0';
	for(i = 1; i <= n; i++){
		start = n - 1;
		current = i;
		parent = ht[current].parent;
		while(parent){
			if(current == ht[parent].left){
				cd[--start] = '0';
			}else{
				cd[--start] = '1';
			}
			current = parent;
			parent = ht[parent].parent;
		}
		
		hc[i-1] = (char *)malloc(sizeof(char) * (n - start));
		strcpy(hc[i - 1], &cd[start]);
	}
	free(cd);
}
void Encode(HuffmanCode *hc, char *alphabet, char *str, char *code){
	int len = 0, i = 0, j;
	code[0] = '\0';
	
	while(str[i]){
		j = 0;
		while(alphabet[j] != str[i]){
			j++;
		}
		strcpy(code + len, hc[j]);
		len = len + strlen(hc[j]);
		i++;
	}
	
	code[len] = '\0';
}
void Decode(HuffmanTree *ht, int m, char *code, char *alphabet, char *decode){
	int position = 0, i, j = 0;
	m = 2 * m - 1;
	while(code[position]){
		for(i = m; ht[i].left && ht[i].right; position++){
			if(code[position] == '0'){
				i = ht[i].left;
			}else{
				i = ht[i].right;
			}
		}
		decode[j] = alphabet[i - 1];
		j++;
	}
	decode[j] = '\0';
}
int main(){
	int i, n = 4, m;
	char test[] = "DBDBDADBCDADBDADBDADACDBDBD";
	char code[100], codel[100];
	char alphabet[] = {'A','B','C','D'};
	int w[] = {5, 7, 2, 13};
	HuffmanTree *ht;
	HuffmanCode *hc;
	m = 2 * n -1;
	ht = (HuffmanTree *)malloc(sizeof(HuffmanTree) * (m + 1));
	hc = (HuffmanCode *)malloc(n * sizeof(char *));
	CreateTree(ht, n, w);
	HuffmanCodeing(ht, n, hc);
	for(i = 1; i<=n; i++){
		printf("字母:%c, 权值:%d, 编码为 %s \n", alphabet[i-1], ht[i].weight, hc[i-1]);
	}
	Encode(hc, alphabet, test, code);
	printf("\n字符串:\n%s \n转换后为:\n%s \n",test, code);
	Decode(ht, n, code, alphabet, codel);
	printf("\n编码:\n%s \n转换后为:\n%s \n", code, codel);
	return 0;
}


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值