哈夫曼树与哈夫曼编码

一、构造哈夫曼树

二、哈夫曼编码

构造哈夫曼树

哈夫曼树的存储:

typedef struct
{
	int weight;//结点的权值
	int parent, lchild, rchild;//节点的双亲、左孩子、右孩子的下标

}HTNode,*HuffmanTree;

算法思想:
1.初始化HT[1,2…2n-1]:lchild=rchild=parent=0;
2.输入初始n个叶子结点:置HT[1, n]的weight值
3.进行n-1次合并,依次产生n-1个结点HT[i],i=n+1…,2n-1
a) 在HT[1,…I-1]中选两个未被选过的两个最小结点HT[s1],HT[s2],s1,s2为两个最小节点的下标
b) xiugai修改HT[s1]和HT[s2]的parent值:
HT[s1].parent = i;
HT[s2].parent = i;
c)修改新产生的HT[i]
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
在这里插入图片描述

void createHuffmanTree(HuffmanTree& HT, int n)
{
	if (n <= 1)
		return;
	//初始化
	int m = 2 * n - 1;//哈夫曼树前n项为叶子结点,后n-1个为度为2的结点,共2n-1个结点
	//下标从1开始,所有空间初始化为0
	for (int i = 1; i <= n; ++i)
	{
		HT[i].parent = 0;
		HT[i].lchild = 0;
		HT[i].rchild = 0;
	}
	//初始化前n项叶子结点的权重
	for (int i = 1; i <= n; i++)
	{
		cin >> HT[i].weight;
	}

	for (int i = n + 1; i <= m; i++)
	{
		int s1, s2;//两个最小权重的下标
		Select(HT, i - 1, s1, s2);//找到最小的两个权重值对应的下标
		//进行合并
		HT[s1].parent = i;
		HT[s2].parent = 1;

		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}

}

哈夫曼编码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//哈夫曼编码
typedef char** HuffmanCode;//动态分配数组存储哈夫曼表
void CreatHuffmanCode(HuffmanTree HT, HuffmanCode& HC, int n)
{
	HC = new char* [n + 1];//分配存储n个字符编码的编码表空间
    char* cd = new char[n];//分配临时存放每个字符编码的动态数组空间
	cd[n - 1] = '\0';//编码结束符
	for (int i = 1; i <= n; i++)//逐个字符求哈夫曼编码
	{
		int start = n - 1;//从start开始指向最后,即编码结束符位置
		int c = i;
		int f = HT[i].parent;//f指向结点c的双亲结点
		while (f != 0)//从叶子结点开始向上回溯,直到根节点
		{
			--start;//回溯一次start向前移动一个位置
			if (HT[f].lchild == c)//若节点c是f的左孩子,则标记为0
				cd[start] == '0';
			else
				cd[start] == '1';//若节点c是f的右孩子,则标记为1
			//继续向上回溯
			c = f;
			f = HT[f].parent;
		}
		//为第i个字符编码分配空间
		HC[i] = new char[n - start];
		//将求得的编码从临时空间cd拷贝到HC的当前行中
		strcpy(HC[i], &cd[start]);
	}
	delete cd;//释放临时空间

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值