哈夫曼树/哈夫曼编码

本算法采用二叉链表来构造二叉树,并用递归算法求哈夫曼编码

构造哈夫曼树

  1. 概念:哈夫曼树为带权路径最短的二叉树
  2. 构造过程:每次选出最小的两个顶点,分别作为左右分支,构造出父节点,父节点权值为两顶点之和,然后将其加入到顶点集合中,并删除之前取出的两个顶点。

哈夫曼编码

  1. 算法思想:通过递归,从根结点往每个叶子结点来进行编码。通过一个临时数组来按照左零右一存储下来,若遇到叶子结点,则将存储的路径作为该字符的编码。

代码

void CreateHuffmanTree(BinaryTree &T, ElemType a[],int n)
{
	TNode **Data = new TNode *[n];
	for (int i = 0; i < n; i++)
	{
		TNode *p = new TNode;
		p->data = a[i];
		p->lchild = NULL;
		p->rchild = NULL;
		Data[i] = p;
	}
	for (int i = 0; i < n - 1; i++) //n个结点 需要n-1次循环
	{
		//每次取两个最小的结点构造哈夫曼树
		TNode *p = new TNode;
		p->data = Data[0]->data + Data[1]->data;
		p->lchild = Data[0];
		p->rchild = Data[1];
		//删除两个最小结点
		for (int i = 2; i < n; i++)
			Data[i - 2] = Data[i];
		//增加新建的结点
		int j = n - i - 2; //j指向未加入哈夫曼树的最大顶点
		if (j != 0)  //j不等于0 用直接插入排序 插入新建的顶点
		{
			if (p->data < Data[j]->data)
			{
				for (j; j >= 0 && p->data < Data[j]->data; j--)
					Data[j + 1] = Data[j];
				Data[j + 1] = p;
			}
			else
				Data[j] = p;
		}
		else //j等于0 说明为哈夫曼树的根结点 直接赋值
			Data[j] = p;
	}
	//最后数组里只有一个结点 则哈夫曼树构造完成
	T = Data[0];
	delete []Data; //释放辅助数组空间
}

void CreateHuffmanCode(BinaryTree T,char *Code[], int n)
{
	static int i = 0; //i为编码字符的编号
	static int j = 0; //j为每个字符应编码的长度 初试话为0
	static char *c = new char[n];
	if (T)
	{	
		
		if (!T->lchild && !T->rchild) //如果为叶子结点 则按照左0右1规则编码
		{
			c[j++] = '\0'; //结束符
			Code[i] = new char[j]; //分配j的长度
			strcpy(Code[i++],c); //串复制
			j--; //取消结束符
		}
		if (T->lchild) //左0
		{
			c[j++] = '0';
			CreateHuffmanCode(T->lchild,Code,n);
			j--;
		}
		if(T->rchild) //右1
		{
			c[j++] = '1';
			CreateHuffmanCode(T->rchild,Code,n);
			j--;
		}
	}
	delete []c;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值