Huffman算法(贪心算法) By ACReaper

终于把Huffman算法实现了 

#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct huffman{
	int weight;
	int parent,lchild,rchild;
}HTNode,*HuffmanTree;
int n;
char buf[MAX_LEN];
void HuffmanCoding(HuffmanTree &HT,int w[],int len_w);
void writeHC(HuffmanTree &HT,HTNode &leaf,int i,char buf[],int &cur);
int min(HuffmanTree &T,int &len_w);
int main(){
	HuffmanTree HT;
	while(scanf("%d",&n) != EOF){
		int *pw = (int *)malloc( (n + 1) * sizeof(int));
		if(!pw){
			printf("Memory Error!,Please Try Again.");
			continue;
		}
		for(int i = 1; i <= n; i++){//输入n个字符对应的权值(分别映射为从a -- z)
			scanf("%d",pw + i);
		}
		HuffmanCoding(HT,pw,n);//进行huffman编码,结果存在HC中
		free(pw);
	}
	return 0;
}
void HuffmanCoding(HuffmanTree &HT,int w[],int len_w){
	int m = 2 * len_w - 1;
	HT = (HuffmanTree)malloc(sizeof(HTNode) * (m + 1));
	if(!HT){
		printf("Something Error in Build HuffmanTree!");
		exit(-1);
	}
	/*  注意给叶子结点赋值和初始化后,各结点依然是离散状态*/
	for(int i = 1 ; i <= len_w; i++){//给叶子结点赋值 
		HT[i].weight = w[i];//1 -- len_w号为叶子 
		HT[i].parent = 0;
		HT[i].lchild = HT[i].rchild = 0;
	}
	
	for(int i = len_w + 1; i <= m; i++){//剩下的非叶子结点,都是度为2的结点,分别初始化 
		HT[i].weight = 0;
		HT[i].parent = 0;
		HT[i].lchild = HT[i].rchild = 0; 
	} 
	
	/*贪心算法,构建huffman树*/ 
	int search_area = len_w;//搜索最小值范围 
	int start = len_w + 1;//其它非叶子结点指针 
	for(;;){
		int min1 = min(HT,search_area);
		int min2 = min(HT,search_area);
		if(min1 == min2){//当只有棵树时,huffman树建立完毕 
			HT[min1].parent = 0;//根节点parent域指向空2 
			break;
		}
		HT[start].weight = HT[min1].weight + HT[min2].weight;
		HT[start].lchild = min2;
		HT[start].rchild = min1;
		HT[min1].parent = HT[min2].parent = start;
		search_area++;
		start++;  
		len_w--;
	} 
	int cur = 0;
	for(int i = 1; i <= n;i++){
		writeHC(HT,HT[i],i,buf,cur);
		cur = 0;
	}
	free(HT);
	
}
int min(HuffmanTree &T,int &len_w){//len_w为叶子结点的个数 
	int m;
	for(int i = 1; i <= len_w; i++){
		if(T[i].parent == 0){
			m = i;
			break;
		}
	}
	for(int i = 1; i <= len_w;i++){
		if(T[m].weight > T[i].weight && T[i].parent == 0){
			m = i;
		}
	}
	T[m].parent = -1;
	return m;
}
void writeHC(HuffmanTree &HT,HTNode &leaf,int i,char buf[],int &cur){
	if(leaf.parent == 0){
		buf[cur] = '\0'; 
		for(int i = cur - 1; i >=0 ; i--)
			printf("%c",buf[i]);
		printf("\n"); 
		return;
	}else{
		if(HT[leaf.parent].lchild == i){
			buf[cur++] = '1';
			writeHC(HT,HT[leaf.parent],leaf.parent,buf,cur);
		}
		if(HT[leaf.parent].rchild == i){
			buf[cur++] = '0';
			writeHC(HT,HT[leaf.parent],leaf.parent,buf,cur);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值