哈夫曼编码实现

#define HuffmanCode char*
typedef struct Node* HuffmanTree;
struct Node{
	int Weight;
	int Parent;
	int Lchild, Rchild;
};

//叶节点为n的哈夫曼树有2*n-1个节点

//用-1表示当前parent未被访问

HuffmanTree CreateHuffmanTree(int *wet, int n)
	{
		int i;
		int Total = 2*n-1;
		HuffmanTree HT = (HuffmanTree)malloc(sizeof(struct Node)*Total);
		if(HT == NULL){
			printf("申请内存失败");
			return NULL;
		}
		for( i  = 0; i < n; i++){//叶节点 初始化 
			HT[i].Parent = -1;
			HT[i].Lchild = -1;
			HT[i].Rchild = -1;
			HT[i].Weight = *wet++;   //这里是权重 
		}
		for(i = n; i < Total; i++){//非叶节点 
			HT[i].Parent = -1;
			HT[i].Lchild = -1;
			HT[i].Rchild = -1;
			HT[i].Weight = 0;  //除叶节点外的 所有节点权重 置为 0
		}
		int min1, min2;//  用于标记每轮选出的权重最小的两个节点 
		for( i = n; i < Total; i++ ){
			SelectMin(HT, i, &min1, &min2); //传递是i 不是n 
		HT[i].Lchild = min1; 
		HT[i].Rchild = min2;
		HT[min1].Parent = i;
		HT[min2].Parent = i;
		HT[i].Weight = HT[min1].Weight + HT[min2].Weight;
		}
		return HT;
	}
void SelectMin(HuffmanTree HT, int k, int *min1, int* min2)
	{
		//int TempMin;
		int min;	
		int i = 0;
		//int min_weight; //存放最小min 的weight 值
		while(HT[i].Parent != -1)
			i++;
		min = i;
		for(; i < k; i++ ){
			if(HT[i].Weight < HT[min].Weight && HT[i].Parent == -1){
				min = i;
			}
		}
		*min1 = min;
		i = 0;//需要 重新 从头部扫描
		while(HT[i].Parent != -1 || i == *min1 ){//保证在本轮循环中 *min2为第二小
			i++;
		}
		min = i;
		for(; i < k; i++ ){
			if(HT[i].Weight < HT[min].Weight && i != *min1 && HT[i].Parent == -1){
				min = i;
			}
		}
		*min2 = min;
		//printf("*min1 = %d, *min2 = %d",*min1, *min2);
	}
void HuffmanCoding(HuffmanTree HT, HuffmanCode *HC, int n)
	{
		HuffmanCode Head;
		//HC已经声明为指针的指针了 不需要 *HC 
		HC = (HuffmanCode*)malloc(sizeof(char* ) * n);//指针的指针 
		if(HC == NULL){ 					//指向每一个code 
			printf("申请空间失败");
			return ;
		}//huffman编码最多需要n-1个字符  尾字符 为'\0' 
		char* code = (char*)malloc(sizeof(char)*n);//每一个哈夫曼编码的指针	
		code[n-1] = '\0';
		int i;
		for(i = 0; i < n; i++ ){
			int current = i;
			int parent = HT[i].Parent;
			int start = n-1;
			while(parent != -1){
				if(HT[parent].Lchild == current)
					code[--start] = '0';
				else if(HT[parent].Rchild == current)
					code[--start] = '1';
				current = parent;
				parent = HT[current].Parent;		
			}
			printf("start = %d\n",start);
			HC[i] = (char*)malloc(sizeof(char)*(n-start));//n-start为字符编码位数 
			if(HC[i] == NULL){						//多一个'\0'位 
				printf("申请内存失败");
				return ;
			}
			strcpy(HC[i],&code[start]); 
		}
		free(code);
		for( i = 0; i < n; i++){
			printf("HuffmanCode of %d is %s\n",HT[i].Weight, HC[i]);
		}
	}	

int main()
	{
		HuffmanTree HT;
		HuffmanCode HC;
		int *wet, i, n;
		printf("请输入节点个数:\n");
		scanf("%d",&n);
		wet = (int*)malloc(sizeof(int)*n);
		printf("Input the weight :\n");
		for(i = 0; i < n; i++ ){
			scanf("%d",&wet[i]); 
		}
		HT = CreateHuffmanTree(wet, n);//  又忘记返回值
		HuffmanCoding(HT, &HC, n);
		
		return 0;
	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值