哈夫曼树

一、定义

(1)专业解释

给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

(2)自己理解

Huffman树,也称最优二叉树,是加权路径长度最短的二叉树。

简单的来说就是权值越大路径越短(权值),这样整体最优(权值*路径长度的和最小)

二、贪心法则构建哈夫曼数

(1)什么是贪心法则

是指在问题求解时,总是做出当前看起来最好的选择。也就是说贪心算法做出的不是整体最优的的选择,而是某种意义上的局部最优解。贪心算法不是对所有的问题都能得到整体最优解。

(2)怎么构建哈夫曼树

从权值最小的值开始构建,开始的时候选择两个权值最低的两个构建一个局部哈夫曼树,然后将这个构建好的数的根节点(权重值为左右节点权重的相加)返回到原来的序列中,构建好的数就从序列中删除了,这样不断选择两个权重最小的两个进行构建,知道序列中的元素个数为0

三、大体结构

1、huffmanNode的声明

template<class T>
struct HuffmanNode
{
	
	HuffmanNode<T>* _left;
	HuffmanNode<T>* _right;
	T _weight;//权值
public:
	HuffmanNode(const T& w)
		:_weight(w)
		, _left(NULL)
		, _right(NULL)
	{}
};

2、huffmanTree的结构

#include"Heap.h"

template<class T>
class HuffmanTree
{
	typedef HuffmanNode<T> Node;
public:
	HuffmanTree();//默认构造函数
	HuffmanTree(const T* a, size_t size);//建立huffmanTree
	void GenerateHuffmanCode();//获取对应的huffman编码,找什么,怎么找

protected:
	Node* _GreatTree(const T* a, size_t size);
protected:
	Node* _root;
};

四、具体实现

1、默认构造函数

HuffmanTree()
	:_root(NULL)
{}

2、构建huffmanTree(使用递归构建)

(1)主函数:

HuffmanTree(const T* a, size_t size)
{
	_root = _GreatTree(a, size);
}

(2)递归函数

Node* _GreatTree(const T* a, size_t size)
{
	struct Compare//建立小根堆
	{
		bool operator()(const Node* l, const Node* r)
		{
			return l->_weight < r->_weight;
		}
	};

	Heap<Node*,Compare> minHeap;//保存的是节点,而不是T类型的具体的数据,若为数那么节点摘下来,那不是后面的数没有了
	
	for (size_t i = 0; i < size; i++)
	{
		minHeap.Push(new Node(a[i]));
	}

	while (minHeap.Size()>1)//不能使用minHeap.Empty(),因为有两两配对,会剩下只有一个数的情况
	{<span style="white-space:pre">				</span>//也就是节点数两两配对,最后会剩下一个root节点
		Node* left = minHeap.Top();
		minHeap.Pop();
		Node* right = minHeap.Top();
		minHeap.Pop();
			
		Node* parent = new Node(left->_weight + right->_weight);
		parent->_left = left;
		parent->_right = right;
		minHeap.Push(parent);
	}
	
	return minHeap.Top();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值