树5.5——赫夫曼树(链式)

这篇博客介绍了如何使用指针来构建赫夫曼树,包括字符权重输入、节点排序、树的构建以及赫夫曼编码和解码的过程。通过示例代码展示了从头开始创建和操作赫夫曼树的详细步骤。

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

找了一圈发现网上大部分赫夫曼树都是顺序存储,记录一下使用指针的赫夫曼树。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 1000 

typedef struct huffNode
{
	char data;
	int weight;
	struct huffNode *lch,*rch,*parent;
}huffNode,*huffTree;
typedef struct
{
	huffTree tree;
	char **list;
}realTree;//这个结构体不重要,为了方便一点而已 

void pre(huffTree H);//遍历 
char **init(huffTree *H);//初始化,该函数结束之后H是树,返回值是根据树建立的码表 
void sort(huffTree node[],int num);//init的辅助子函数 
char *get(huffTree H,huffTree *tempUse,int position);//init的辅助子函数,返回树中某个字符的码表 
void code(realTree T);//赫夫曼编码函数 
void print(char *lineList);//code的辅助子函数,打印某个字符的码 
void encode(realTree T);//赫夫曼译码函数 
int main()
{
	realTree t1;
	t1.list=init(&t1.tree);
	encode(t1);
	return 0;
}
void pre(huffTree H)
{
	if(H!=NULL)
	{
		printf("%c",H->data);
		pre(H->lch);
		pre(H->rch);
	}
}
char **init(huffTree *H)
{
	int i,j;
	
	//得到字符集字符数量 
	int num;
	printf("Enter character number>");
	scanf("%d",&num);
	getchar();//去除换行符
	
	//输入每个字符及其权值
	char ch[num];
	int weight[num];
	printf("Enter each character and weight>\n");
	for(i=0;i<num;i++)
	{
		scanf("%c",&ch[i]);
		scanf("%d",&weight[i]);
		getchar();
	}
	
	//建立每个节点 
	huffTree node[num];
	huffTree tempUse[num];//这一步用不到,下面"给每个字符编码"环节用 
	for(i=0;i<num;i++)
	{
		node[i]=(huffTree)malloc(sizeof(huffNode));
		node[i]->data=ch[i];
		node[i]->weight=weight[i];
		//左右孩子还是初始化一下好,防止要使用 
		node[i]->lch=NULL;
		node[i]->rch=NULL;
		
		tempUse[i]=node[i];
	}
	
	//建立整棵树 
	huffTree UP;
	for(i=num;i>1;i--)
	{
		sort(node,i);
		
		UP=(huffTree)malloc(sizeof(huffNode));
		UP->data=0;
		UP->weight=node[i-2]->weight+node[i-1]->weight;
		UP->lch=node[i-2];
		UP->rch=node[i-1];
		
		node[i-2]->parent=UP;//反正下个循环也会sort到合适的地方 
		node[i-1]->parent=UP;
		node[i-2]=UP;
		node[i-1]=NULL;//这个指针不再使用,防止意外置为空 
	}
	UP->data=num;
	(*H)=UP;
	
	//给每个字符编码 
	char **list=(char**)malloc(sizeof(char*)*num);
	char temp;
	int length;
	for(i=0;i<num;i++)
	{
		list[i]=get(UP,tempUse,i);
		length=strlen(list[i]);
		for(j=1;j<=length/2;j++)
		{
			temp=list[i][j];
			list[i][j]=list[i][length-j];
			list[i][length-j]=temp;
		}
	}
	
	return list;
}
void sort(huffTree node[],int num)
{
	huffTree temp;
	for(int i=0;i<=num-2;i++)
		for(int j=i+1;j<=num-1;j++)
		{
			if(node[i]->weight<node[j]->weight)
			{
				temp=node[i];
				node[i]=node[j];
				node[j]=temp;
			}
		}
}
char *get(huffTree H,huffTree *tempUse,int position)
{
	int order;//计数器 
	int length=H->data+1;
	char *ret=(char*)malloc(sizeof(char)*length);
	ret[0]=tempUse[position]->data;
	for(order=1;order<length;order++)ret[order]=0;
	
	huffNode *ptr=tempUse[position];//可以用huffTree,为了表明是个指针用了huffNode*
	huffNode *pre=ptr;
	
	order=1;
	while(ptr!=H)
	{
		ptr=ptr->parent;
		if(ptr->lch==pre)ret[order]='0';
		else ret[order]='1';
		pre=ptr;
		order++;
	}
	
	return ret;
}
void code(realTree T)
{
	char str[MAXSIZE];
	printf("Enter coding string>");
	scanf("%s",str);
	
	int i,j;
	int stringLen=strlen(str);
	int listLen=T.tree->data;
	printf("Huffcode>\n");
	for(i=0;i<stringLen;i++)
	{
		for(j=0;j<listLen;j++)
		{
			if(T.list[j][0]==str[i])
			{
				print(T.list[j]);
			}
		}
	}
} 
void print(char *lineList)//这个函数其实没那么必要,只是为了code函数里结构清晰一些 
{
	int length=strlen(lineList);
	for(int i=1;i<length;i++)
	{
		printf("%c",lineList[i]);
	}
}
void encode(realTree T)
{
	char code[MAXSIZE];
	printf("Enter code>");
	scanf("%s",code);
	
	huffNode *ptr=T.tree;
	for(int i=0;code[i]!=0;i++)
	{
		if(code[i]=='0')ptr=ptr->lch;
		else ptr=ptr->rch;
		
		if(ptr!=T.tree&&ptr->data!=0)
		{
			printf("%c",ptr->data);
			ptr=T.tree;
		}
	}
}
/*
5
a 5
b 4
c 4
d 2
e 1

//下面的根据运行的函数输入
aedcbadbecbea//函数code
0011111010010011001111100111100//函数encode
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值