nyoj 801 Huffman编码

本文详细介绍了一种构建Huffman树的方法,并实现了相应的编码过程。通过动态内存分配和释放技术来构建Huffman树,提高了程序运行效率。文章还提供了一个具体的实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题 : http://acm.nyist.net/JudgeOnline/problem.php?pid=801 

HuffmanTree 建立与编码: http://blog.youkuaiyun.com/zark721/article/details/76516189

//nyoj 801
//构建huffman树的过程稍做修改即可
//每一次动态申请内存malloc,要手动释放free,防止内存泄漏,还可以提高速度。 
//因为 malloc是从堆区申请空间,函数结束后不会自动释放,如果不人为地释放的话,要等到程序结束后,系统才会自动回收,累积到一定程度,程序会崩溃(摘自百度)
#include<iostream>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct input
{
	char ch;
	int w;
}in[101];
typedef struct Node
{
	char ch;
	int weight;
	int lchild;
	int rchild;
	int parent;	
}HTNode,*HuffmanTree;//存放树的所有节点
typedef char**HuffmanCode ;//存放每一个叶子结点的编码
void strcpy(char *to,char * from)
{
	int i=0;
	while(from[i]!='\0')
	{
		to[i]=from[i];
		i++;
	}
	to[i]='\0';
} 
void findmin(HuffmanTree ht,int k,int &min1,int &min2);
int min(HuffmanTree ht,int k);
HuffmanTree HuffmanTreeBuild(int n)//建树函数 
{
	int i;
	int total=2*n-1;//树的节点总数 
	HuffmanTree ht=(HTNode *) malloc(total*sizeof(HTNode));
	//初始化 
	for(i=0;i<n;i++) 
	{
		ht[i].lchild=-1;
		ht[i].rchild=-1;
		ht[i].parent=-1;
		ht[i].ch=in[i].ch;
		ht[i].weight=in[i].w; 
	}
	for(;i<total;i++)
	{
		ht[i].lchild=-1;
		ht[i].rchild=-1;
		ht[i].parent=-1;
		ht[i].weight=0; 
	}
	int min1,min2;//权值最小的两棵二叉树 
	for(i=n;i<total;i++)
	{
		findmin(ht,i,min1,min2);
		ht[i].lchild=min1;
		ht[i].rchild=min2; 
		ht[min1].parent=ht[min2].parent=i;
		ht[i].ch=ht[ht[i].lchild].ch;
		ht[i].weight=ht[min1].weight+ht[min2].weight;
	}
	return ht;
}
void findmin(HuffmanTree ht,int k,int &min1,int &min2)
{
	min1=min(ht,k);
	min2=min(ht,k);
}
int min(HuffmanTree ht,int k)
{
	int i=0;
	int min;
	int minw;
	char ch;
	while(ht[i].parent!=-1)
	{
		i++;
	}
	min=i;
	minw=ht[i].weight;
	ch=ht[i].ch;
	i++;
	while(i<k)
	{
		if(ht[i].parent==-1 && ht[i].weight<=minw)
		{
			if(ht[i].weight<minw || (ht[i].weight==minw && ht[i].ch<ch))
			{
				min=i;
				minw=ht[i].weight;
				ch=ht[i].ch;
			}
		}
		i++;
	}
	ht[min].parent=1;
	return min;
}
HuffmanCode HuffmanTreeCoding(HuffmanTree ht,int n)
{
	HuffmanCode hc=(HuffmanCode)malloc(n*sizeof(char *));
	int i;
	char *tmp=(char *)malloc(n*sizeof(char));
	tmp[n-1]='\0';
	for(i=0;i<n;i++)
	{
		int start=n-1;
		int cur=i;
		int parent=ht[i].parent;
		while(parent!=-1)
		{
			if(ht[parent].lchild==cur){
				tmp[--start]='0';
			}else{
				tmp[--start]='1';
			}
			cur=parent;
			parent=ht[parent].parent;
		}
		int len=n-start;
		hc[i]=(char *)malloc(len*sizeof(char));
		strcpy(hc[i],tmp+start);
	}
	return hc;
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		getchar();
		for(int i=0;i<n;i++)
		{
			scanf("%c %d",&in[i].ch,&in[i].w);
			getchar();
		}
		HuffmanTree ht=HuffmanTreeBuild(n);
		HuffmanCode hc=HuffmanTreeCoding(ht,n);
		for(int i=0;i<n;i++)
		{
			printf("%c:%s\n",in[i].ch,hc[i]);
		}
		free(ht); //释放内存速度快了3倍。 
		free(hc);
	} 
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值