栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

构建哈夫曼树C++ 完整的代码(仅构建不是遍历)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

构建哈夫曼树C++ 完整的代码(仅构建不是遍历)

有几个重要的函数模块

initialize()为我们的哈夫曼树先开辟空间初始化  但此时还没有开始构建哈夫曼树

input()输入我们哈夫曼树的数据 但还没开始构建哈夫曼树

select()寻找权重最小 次小的两个结点

creat()构建我们的哈夫曼树 但要用到select

最难的是select函数和creat函数 把这两个理解好了就行了  其他两个函数都很简单。

首先要理解哈夫曼树的话 你不能用二叉树的知识去理解 因为二叉树类似链表链接 

而这个哈夫曼树和数组很像 所以你要分开理解 不要混在一起 

代码参考构造哈夫曼树代码实现(C++)_果酱包的博客-CSDN博客_哈夫曼树代码实现

但首先你要知道哈夫曼树是什么  我觉得哈夫曼树那个表格很难理解 你要多看一会儿 

那个列表画的太tm抽象了  我当时就用二叉树去理解的他 半天弄不清那个下标的含义 

但如果你用数组去理解的话 很容易理解 

 请大家一定要看我代码旁边的注释 很重要 这是这篇文章的精髓 也是我花了很多时间做的东西!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#include
using namespace std;
int total = 0;
struct student
{
	char data=0;
	int weight=-1;
	int parent=-1;
	int left=-1;
	int right=-1;
};//这些数据默认为-1  不要为0 因为我的数组一开始有下标为0的结点 如果parent left或者right=0后 会出现问题 等会初始化的时候就更方便 不用再重新给初始化他们赋值为0
 
void select(student*& tree, int n, int& s1, int& s2);
void show(student*& tree, int n);
void initialize(student*& tree, int n);
void input_data(student*& tree, int n);
void show(student*& tree, int n);
 
void initialize(student*& tree, int n)//为我们的哈夫曼树先开辟空间初始化  但此时还没有开始构建哈夫曼树
{
	if (n <= 1)//
	{
		return;
	}
	total = 2 * n - 1;//m的 含义
	tree = new student[total];//
}
 
void input_data(student*& tree, int n)//输入我们哈夫曼树的数据 但还没开始构建哈夫曼树
{
 
 
	for (int j = 0; j < n; ++j)
	{
		cout << "请输入我们的第" << j << "个叶子结点的权重" << endl;
		cin >> tree[j].weight;
	}
 
}
 
void creat(student*& tree, int n)//构建我们的哈夫曼树 但要用到select
{
	int valuemin1 = 0;
	int valuemin2 = 0;
	for (int i = n; i < total; i++)
	{
		select(tree, i, valuemin1, valuemin2);
		
 
 
		//此时i的下标已经是新构建出来的结点了 
		//以下两行代码的意思比如 有叶子结点 2 3 4 5  当i=4时,说明是新节点 该新节点是由2 3结点构成 所以该结点值为5,2 3的parent是该节点的下标所以2 3的parent等于4
		tree[valuemin1].parent = i;
		tree[valuemin2].parent = i;
		//-----------------------------
 
		tree[i].left = valuemin1;
		tree[i].right = valuemin2;
		//-------------------------------
		tree[i].weight = tree[valuemin1].weight + tree[valuemin2].weight;//i结点的权重为两个子节点的合
 
	}
}
 
void select(student *&tree, int n, int& s1, int& s2) {
	int min;
	
	for (int i = 1; i <= n; i++) 
	{
		if (tree[i].parent == 0) //为什么要设置这个条件?
			//因为parent等于0时 代表这个结点还没参与哈夫曼树的构建 说明还是个零散的结点(散结点)所谓散结点就是还没参与哈夫曼树构造的结点 但你要寻找范围只能是在还没参与的结点里面寻找
		{
			min = i;
			break;
		}
	}
 
	for (int j = 0; j < n; ++j) 
	{
		if (tree[j].parent == 0) //在散结点中寻找 所谓散结点就是还没参与哈夫曼树构造的结点 这类节点parent为0
		{
			if (tree[j].weight < tree[min].weight)
				min = j;
		}
	}
	s1 = min;
 
	for (int i = 0; i < n; ++i) 
	{
		   //首先寻找范围必须是零散的结点 还没参与构建哈夫曼树 
			//parent=0说明是零散结点
			//由于s1的值已经代表第一小结点了 所以i不能等于s1
		if (tree[i].parent == 0 && i != s1)
		{
			min = i;
			break;
		}
	}
	for (int j = 0; j > n;
	student* tree;
	initialize(tree,n);//为我们的哈夫曼树先开辟空间初始化  但此时还没有开始构建哈夫曼树
	show(tree, n);
 
	input_data(tree, n);//输入我们哈夫曼树的数据 但还没开始构建哈夫曼树
 
 
	creat(tree, n);//构建我们的哈夫曼树
	show(tree, n);
 
 
	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/879286.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号