数据结构-哈夫曼树的建立

#include <iostream>
#include <iomanip>
using namespace std;

typedef struct {
	int weight;//权值
	int parent, lchild, rchild;//双亲结点和左右孩子结点
}HTNode, * HuffmanTree;

void Select(HuffmanTree& HT, int n, int& s1, int& s2);//每次选择出权值最小的两个结点,用s1 s2返回以用来合并新结点
void CreateHuffmanTree(HuffmanTree& HT, int* w, int n);//建立哈夫曼树,结点存在与数组w中,结点个数为n
void DisplayHuffmanTree(HuffmanTree HT, int n);

void Select(HuffmanTree& HT, int n, int& s1, int& s2) {
	int min = 0;//临时变量,用于存储权值最小的元素
	for (int i = 0; i < n; i++) {//第一轮循环,寻找一个无父母的结点
		if (HT[i].parent == -1) {
			min = i; break;
		}
	}
	for (int i = min + 1; i < n; i++) {//第二轮循环,遍历min之后的所有结点,将权值最小的结点存入min
		if (HT[i].parent == -1)
			if (HT[i].weight < HT[min].weight)
				min = i;
	}
	s1 = min;//找到了第一个最小结点
	//重复上述过程,但要确保所找到元素非s1
	for (int i = 0; i < n; i++) {//第一轮循环,寻找一个无父母的结点
		if (HT[i].parent == -1 && i!=s1) {
			min = i; break;
		}
	}
	for (int i = min + 1; i < n; i++) {//第二轮循环,遍历min之后的所有结点,将权值最小的结点存入min
		if (HT[i].parent == -1)
			if (HT[i].weight < HT[min].weight && i!=s1)
				min = i;
	}
	s2 = min;//找到了第二个最小结点
}
void CreateHuffmanTree(HuffmanTree& HT, int* w, int n) {
	if (n <= 1)return;//如果结点为1个或不存在则直接完成建立
	int m = 2 * n - 1;//根据公式,总结点个数为2n-1个
	HT = new HTNode[m];//分配m个空间用来建立哈夫曼树
	if (!HT)exit(0);
	for (int i = 0; i < n; i++) {//前n个结点用来存储初始的所有叶子结点
		HT[i].parent = -1;
		HT[i].lchild = -1;
		HT[i].rchild = -1;
		HT[i].weight = w[i];
	}
	for (int i = n; i < m; i++) {//后面的结点用来存储哈夫曼树的非叶子结点,先进行初始化
		HT[i].parent = -1;
		HT[i].lchild = -1;
		HT[i].rchild = -1;
		HT[i].weight = 0;
	}

	for (int i = n; i < m; i++) {
		int s1, s2;
		Select(HT, i, s1, s2);//从0-i-1一共i个结点中选出最小的s1和s2
		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 DisplayHuffmanTree(HuffmanTree HT, int n) {
	int m = 2 * n - 1;
	cout << "weight" << " " << "lchild" << " " << "rchild" << endl;
	for (int i = 0; i < m; i++)
	{
		cout << setw(4) << HT[i].weight << setw(7) << HT[i].lchild << setw(7) << HT[i].rchild << endl;
	}
}


int main()
{
	HuffmanTree HT;
	cout << "请输入叶子结点的个数(<=100):" << endl;
	int i, n;
	cin >> n;
	int* w = new int[n];
	cout << "请依次输入个结点的权值(为正整型值):" << endl;
	for (i = 0; i < n; i++)
		cin >> w[i];
	CreateHuffmanTree(HT, w, n);
	DisplayHuffmanTree(HT, n);
	return 0;
}

实验样例

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的大鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值