Huffmanアルゴリズム(欲張りアルゴリズム)By ACReaper

2729 ワード

やっとハフマンアルゴリズムを実現した
#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("
"); 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); } } }