数据结构教程—哈夫曼树的构造算法

哈夫曼树算法如下

(1)根据给定的n个权值,使对应节点构成n棵二叉树的森林,其中每棵二叉树都只有一个根节点,其左右子树均为空。
(2)在森林中选取两棵节点权值最小的子树分别作为左右子树构造一棵新的二叉树,且置新的二叉树的根节点的权值为其左右子树上根节点的权值之和。
(3)在森林中,用新得到的二叉树替代选取的两棵树。
(4)重复(2)和(3),直到只含有一棵树为止,这棵树便是哈夫曼树。

构造过程图如下:
数据结构教程—哈夫曼树的构造算法_第1张图片

测试分析

为了便于操作,使用数组存放二叉树,并用一个HTNode存放节点,数组下标为【0~n-1】的位置存放用来构造哈夫曼树的节点(此例中存放的是权重域为1,3,5,7这4个节点),一共将要用到数组的【0】到【2n-1】(不包括【2n-1】)个节点(因为有n个叶子节点且只有二度节点的二叉树的节点数为2*n-1)。按照构造过程图可知,输出结果应为:1 3 5 7 4 9 16.

C++代码实现

头文件及类定义:

#include
using namespace std;

#define MaxSize 20

typedef struct {
     
	char data;			//节点值
	double  weight;		//权重
	int parent;			//双亲节点
	int lchild;			//左孩子节点
	int rchild;			//右孩子节点
}HTNode;

构造哈夫曼树的算法:

void CreateHT(HTNode ht[],int n){
     
	int i, j, k;
	int lnode, rnode;//lnode存放最小权值节点的位置,rnode存放权值次小节点位置
	double min1, min2;//min1存放最小权值,min2存放次小权值

	for (i = 0; i < 2 * n - 1; i++)//初始化所有相关节点域为-1
		ht[i].parent = ht[i].lchild = ht[i].rchild = -1;

	//第一层循环,第一次遍历[0]到[n-1]个元素(所有待构造的节点存放在这段区间)
	//每次循环会产生一个新的节点,所以每次循环结束后i++,
	for (i = n; i < 2 * n - 1; i++) {
     
		min1 = min2 = 32767;//初始化
		lnode = rnode = -1;//初始化

		//第二层循环,第一次遍历[0]到[n-1]个元素找到两个最小权值节点并以此构造新节点,插入到末尾
		for (k = 0; k <= i - 1; k++) 
		{
     
			if (ht[k].parent == -1) 
			{
     //只在尚未构造二叉树的节点中查找

				if (ht[k].weight < min1) 
				{
     //当k点权值小于保存最小权值的点的值时
					min2 = min1;
					rnode = lnode;//将最小权值点赋值给次小权值点
					min1 = ht[k].weight;
					lnode = k;//将k点赋值为最小权值点
				}
				else if (ht[k].weight < min2) 
				{
     //当k点权值大于min1,小于min2时
					min2 = ht[k].weight;
					rnode = k;
				}
			}
			
		}
		//用两个最小节点创建新节点,该新节点将在下一次循环参与比较
		ht[i].weight = ht[lnode].weight + ht[rnode].weight;//为新节点设置权值
		ht[i].lchild = lnode;//设置其左右孩子节点
		ht[i].rchild = rnode;
		ht[lnode].parent = i;//设置当前两最小节点的双亲节点
		ht[rnode].parent = i;

	}

}

主函数测试及运行结果:

int main() {
     

	HTNode ht[MaxSize];

	HTNode node1;
	HTNode node2;
	HTNode node3;
	HTNode node4;

	node1.weight = 1;
	node2.weight = 3;
	node3.weight = 5;
	node4.weight = 7;

	ht[0] = node1;
	ht[1] = node2;
	ht[2] = node3;
	ht[3] = node4;

	CreateHT(ht, 4);

	for (int i = 0; i < 2 * 4 - 1; i++)
		cout << ht[i].weight << " ";
	cout << endl;

}

数据结构教程—哈夫曼树的构造算法_第2张图片

你可能感兴趣的:(java类库,数据结构,二叉树,数据结构,c++,算法)