哈夫曼编码的核心代码

首先大家要知道什么是哈夫曼编码

核心就是左路径编码为0, 右路径编码为1

具体思路哈夫曼编码算法--我只想简单点__Saoke的博客-CSDN博客_哈夫曼编码算法

下面我要传一下核心的代码

void Huffman_code11111111111111(student tree[], int n)
{
	if (tree[n].parent == -1)//这里的-1是parent的默认值 parent为-1的点很明显是树根
		return;
	Huffman_code11111111111111(tree, tree[n].parent);
		if (tree[tree[n].parent].left == n)
		{
			cout << 0;
		}
		else
		{
			cout << 1;
		}
}

这段递归大家用心理解 

递归哪里tree[n].parent 很容易搞混哦  耐心看看

先逐步递归  从树的最下层递归到最上层,然后输出0或者1  大家写个二叉树 然后自己顺着代码模拟下

完整代码

#include<iostream>
#include<queue>
using namespace std;
int total;
struct student
{
	string code = "";
	char data = 0;
	int weight = -1;
	int parent = -1;
	int left = -1;
	int right = -1;
};//这些数据默认为0 等会初始化的时候就更方便 不用再重新给初始化他们赋值为0




void select(student tree[], int n, int& s1, int& s2);



void input_data(student tree[], int n)//输入我们哈夫曼树的数据 但还没开始构建哈夫曼树
{
	for (int j = 0; j < n; ++j)
	{

		cin >> tree[j].data;
	}

	for (int j = 0; j < n; ++j)
	{

		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 = 0;

	for (int i = 1; i <= n; i++)
	{
		if (tree[i].parent == -1) //为什么要设置这个条件?
			//因为parent等于0时 代表这个结点还没参与哈夫曼树的构建 说明还是个零散的结点(散结点)所谓散结点就是还没参与哈夫曼树构造的结点 但你要寻找范围只能是在还没参与的结点里面寻找
		{
			min = i;
			break;
		}
	}

	for (int j = 0; j < n; ++j)
	{
		if (tree[j].parent == -1) //在散结点中寻找 所谓散结点就是还没参与哈夫曼树构造的结点 这类节点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 == -1 && i != s1)
		{
			min = i;
			break;
		}
	}
	for (int j = 0; j < n; ++j)
	{
		if (tree[j].parent == -1 && j != s1)
		{
			if (tree[j].weight < tree[min].weight)
				min = j;
		}
	}
	s2 = min;//s2是第二小权重结点的代号(下标)
}


void tt(int m[])
{
	for (int i = 0; i < 10; i++)
	{
		cin >> m[i];
	}
}


void Huffman_code11111111111111(student tree[], int n)
{
	if (tree[n].parent == -1)
		return;
	Huffman_code11111111111111(tree, tree[n].parent);
		if (tree[tree[n].parent].left == n)
		{
			cout << 0;
		}
		else
		{
			cout << 1;
		}
}
int main()
{

	int n = 0;
	cin >> n;





	total = 2 * n - 1;
	student tree[100];

	input_data(tree, n);//输入我们哈夫曼树的数据 但还没开始构建哈夫曼树



	creat(tree, n);//构建我们的哈夫曼树

	cout << endl;
	for (int i = 0; i < n; ++i)
	{
		cout << i << ":" << endl;
		Huffman_code11111111111111(tree, i);
		cout << endl;
	}
	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杨骅麟(Patrick Young)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值