构建哈夫曼树 (笔记)

构造哈夫曼树

每个节点的存储结构设计如下图:

构建哈夫曼树 (笔记)_第1张图片

哈夫曼树的存储表示代码:

// 哈夫曼树的存储表示
typedef struct 
{
	int weight;//节点的权值
	int parent, lchild, rchild;//节点的双亲、左孩子、右孩子的下标
}HTNode,*HuffmanTree;

所需的select函数如下:

//构建select函数
void Select(HuffmanTree HT, int m, int* s1, int* s2)
{	//从这m个数里边选择最小的2个//把第一个进行标记就ok 
	int i;//从下标为1的位置开始计数 
	//int min=HT[1].weight;这里直接赋值不合理,假如第一次那个1就是最小被选选中,那么第2次还是被选中 
	int min1 = 1000;
	int min2 = 1000;//规定一个特别大的数 

	for (i = 1; i <= m; i++)
	{
		if (HT[i].parent == 0 && min1 > HT[i].weight) 
		{
			min1 = HT[i].weight;
			*s1 = i;
		}
	}
	for (i = 1; i <= m; i++)
	{//注意这个I!=*s1标记min 
		if (i != (*s1) && HT[i].parent == 0)
			if (HT[i].weight < min2) 
			{
				min2 = HT[i].weight;
				*s2 = i;
			}

	}
}

创建哈夫曼树的函数如下:

//创建哈夫曼树
void  createHuffmanTree(HuffmanTree &HT, int n)
{
	int s1, s2;
	//构造哈夫曼树HT
	if (n <=1)
	{
		return;
	}
	int m = 2 * n - 1;
	HT = new HTNode[m + 1];
	for (int i = 0; i <= m; i++)
	{
		HT[i].parent = 0;
		HT[i].lchild = 0;
		HT[i].rchild = 0;
	}
	for (int i = 0; i <= n; i++)
	{
		cin >> HT[i].weight;
	}
//初始化结束,开始创建哈夫曼树..
	for (int i = n + 1; i <= m; i++)
	{
		Select(HT, i - 1, &s1, &s2);//调用select函数
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}

输出哈夫曼树的函数

//输出哈夫曼树..
void outHuffmanTree(HuffmanTree HT, int n)
{
	if (HT == NULL)
	{
		printf("无huffmantree\n");
	}
	int i;
	printf("输出huffmantree表格\n");
	printf("结点 weight parent lchild rchild\n");
	for (i = 1; i < 2 * n; i++)
	{
		//是2n-1个结点,申请了2n个位置0-2n-1(这是2n个用1-2n-1) 
		printf("%2d %6d %6d %6d %6d\n", i, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
	}
}

完整的代码:

#include

using namespace std;


// 哈夫曼树的存储表示
typedef struct 
{
	int weight;//节点的权值
	int parent, lchild, rchild;//节点的双亲、左孩子、右孩子的下标
}HTNode,*HuffmanTree;


//构建select函数
void Select(HuffmanTree HT, int m, int* s1, int* s2)
{	//从这m个数里边选择最小的2个//把第一个进行标记就ok 
	int i;//从下标为1的位置开始计数 
	//int min=HT[1].weight;这里直接赋值不合理,假如第一次那个1就是最小被选选中,那么第2次还是被选中 
	int min1 = 1000;
	int min2 = 1000;//规定一个特别大的数 

	for (i = 1; i <= m; i++)
	{
		if (HT[i].parent == 0 && min1 > HT[i].weight) 
		{
			min1 = HT[i].weight;
			*s1 = i;
		}
	}
	for (i = 1; i <= m; i++)
	{//注意这个I!=*s1标记min 
		if (i != (*s1) && HT[i].parent == 0)
			if (HT[i].weight < min2) 
			{
				min2 = HT[i].weight;
				*s2 = i;
			}

	}
}


//创建哈夫曼树
void  createHuffmanTree(HuffmanTree &HT, int n)
{
	int s1, s2;
	//构造哈夫曼树HT
	if (n <=1)
	{
		return;
	}
	int m = 2 * n - 1;
	HT = new HTNode[m + 1];
	for (int i = 0; i <= m; i++)
	{
		HT[i].parent = 0;
		HT[i].lchild = 0;
		HT[i].rchild = 0;
	}
	for (int i = 0; i <= n; i++)
	{
		cin >> HT[i].weight;
	}
//初始化结束,开始创建哈夫曼树..
	for (int i = n + 1; i <= m; i++)
	{
		Select(HT, i - 1, &s1, &s2);//调用select函数
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}

//输出哈夫曼树..
void outHuffmanTree(HuffmanTree HT, int n)
{
	if (HT == NULL)
	{
		printf("无huffmantree\n");
	}
	int i;
	printf("输出huffmantree表格\n");
	printf("结点 weight parent lchild rchild\n");
	for (i = 1; i < 2 * n; i++)
	{
		//是2n-1个结点,申请了2n个位置0-2n-1(这是2n个用1-2n-1) 
		printf("%2d %6d %6d %6d %6d\n", i, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
	}
}

int  main()
{
		int n;
		HuffmanTree HT;
		printf("下面进行huffmantree的创建\n请输入你想要输入的结点个数:\n");
		cin >> n;
		createHuffmanTree(HT, n);
		printf("创建Huffman tree完成\n");
		outHuffmanTree(HT, n);//HT里边的值就是那棵哈夫曼树的地址,这样就需要考虑之前的单链表,与2叉数的问题了 
        system(pause);
		return 0;
}

 

你可能感兴趣的:(c++,算法)