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

有几个重要的函数模块

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

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

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

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

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

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

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

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

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

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

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

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

#include<iostream>
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);
		/*该select函数运行过后 作用是给valuemin1 valuuemin2赋值
		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; ++j) 
	{
		if (tree[j].parent == 0 && j != s1) 
		{
			if (tree[j].weight < tree[min].weight)
				min = j;
		}
	}
	s2 = min;//s2是第二小权重结点的代号(下标)
}
 
 
 
 
 
void show(student* &tree,int n)
{
	cout << "----------------------------------" << endl;
	
	for (int i = 0; i < total; i++)
	{
		cout << i << "   "<<tree[i].data<<"    " << tree[i].weight << "   " << tree[i].parent << "   " << tree[i].left << "   " << tree[i].right << endl;
	}
	
	cout << "-------------------------" << endl;
	
}
 
int main()
{
	int n;
	cout << "请输入我们有几个叶子节点" << endl;
	cin >> n;
	student* tree;
	initialize(tree,n);//为我们的哈夫曼树先开辟空间初始化  但此时还没有开始构建哈夫曼树
	show(tree, n);
 
	input_data(tree, n);//输入我们哈夫曼树的数据 但还没开始构建哈夫曼树
 
 
	creat(tree, n);//构建我们的哈夫曼树
	show(tree, n);
 
 
	return 0;
}

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的C++代码示例,用于生成哈: ```cpp #include <iostream> #include <queue> using namespace std; // 哈节点 struct HuffmanNode { char data; int frequency; HuffmanNode* left; HuffmanNode* right; HuffmanNode(char data, int frequency) { this->data = data; this->frequency = frequency; left = nullptr; right = nullptr; } }; // 用于比较节点频率的函数对象 struct Compare { bool operator()(HuffmanNode* a, HuffmanNode* b) { return a->frequency > b->frequency; } }; // 构建 HuffmanNode* buildHuffmanTree(priority_queue<HuffmanNode*, vector<HuffmanNode*>, Compare>& pq) { while (pq.size() > 1) { HuffmanNode* left = pq.top(); pq.pop(); HuffmanNode* right = pq.top(); pq.pop(); // 创建一个新节点作为父节点 HuffmanNode* parent = new HuffmanNode('$', left->frequency + right->frequency); parent->left = left; parent->right = right; pq.push(parent); } return pq.top(); } // 打印哈编码 void printHuffmanCodes(HuffmanNode* root, string code) { if (root == nullptr) { return; } if (root->data != '$') { // 叶子节点 cout << root->data << ": " << code << endl; } printHuffmanCodes(root->left, code + "0"); printHuffmanCodes(root->right, code + "1"); } int main() { string text = "Hello, World!"; int frequency[256] = {0}; // 统计字符频率 for (char c : text) { frequency[c]++; } // 构建优先队列,按照频率排序 priority_queue<HuffmanNode*, vector<HuffmanNode*>, Compare> pq; for (int i = 0; i < 256; i++) { if (frequency[i] > 0) { HuffmanNode* node = new HuffmanNode(static_cast<char>(i), frequency[i]); pq.push(node); } } // 构建 HuffmanNode* root = buildHuffmanTree(pq); // 打印哈编码 printHuffmanCodes(root, ""); return 0; } ``` 上述代码中,首先统计了给定文本中字符的频率。然后,使用优先队列来构建,每次从队列中取出两个频率最低的节点,并创建一个新的父节点连接它们。最后,通过递归遍,生成每个字符的哈编码并进行打印输出。 请注意,以上只是一个简单的示例,并没有处理特殊字符或文件输入输出。在实际应用中,可能需要进行相关的扩展和修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杨骅麟(Patrick Young)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值