哈夫曼编码树类及其编码应用

本文介绍了哈夫曼编码树的构建过程,包括构造函数中对字符和权值的处理、排序以及编码的设置。还提供了字符串转编码和编码转字符串的方法,并在测试程序中展示了整个过程的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

哈夫曼编码树类(构造哈夫曼编码树、字符串转编码、编码转字符串):

测试程序:


哈夫曼编码树类(构造哈夫曼编码树、字符串转编码、编码转字符串):

#pragma once

#include <iostream>
#include <string>

using namespace std;

class encoding_tree
{
private:
	struct node
	{
		node* _left = nullptr;
		node* _right = nullptr;
		int _weight = 0;
		char _character= '#';
		string _code = "";
	};
	const int _max_node = 1000;
	int _node_number;
	node* _node_list = new node[_max_node];

	//以下是不被看见的成员函数
	//按照权值排序
	template<typename T>
	void sort(T* t_list, int* weight_list, int length)
	{
		for (int x = 0; x < length - 1; x++)
		{
			for (int y = 0; y < length - x - 1; y++)
			{
				if (weight_list[y] > weight_list[y + 1])
				{
					int temp_weight;
					T temp_t;
					temp_weight = weight_list[y];
					temp_t = t_list[y];
					weight_list[y] = weight_list[y + 1];
					t_list[y] = t_list[y + 1];
					weight_list[y + 1] = temp_weight;
					t_list[y + 1] = temp_t;
				}
			}
		}
	}

	//删除列表中的元素
	template<typename T>
	void erase(T* t_list, int& length, int position)
	{
		for (int x = position; x < length - 1; x++)
		{
			t_list[x] = t_list[x + 1];
		}
		length--;
	}

	//设置编码,这里采用的是递归的深度优先遍历
	void set_code(node* temp_node, string code)
	{
		if (temp_node == nullptr)
		{
			return;
		}
		temp_node->_code = code;
		set_code(temp_node->_left, code + "0");
		set_code(temp_node->_right, code + "1");
	}

	//根据字符深度优先搜索
	node* depth_first_search(node* temp_node, char temp_character)
	{
		node *temp_node_1, *temp_node_2;
		if (temp_node == nullptr)
		{
			return nullptr;
		}
		if (temp_node->_character == temp_character)
		{
			return temp_node;
		}
		temp_node_1 = depth_first_search(temp_node->_left, temp_character);
		if (temp_node_1 != nullptr && temp_node_1->_character == temp_character)
		{
			return temp_node_1;
		}
		temp_node_2 = depth_first_search(temp_node->_right, temp_character);
		if (temp_node_2 != nullptr && temp_node_2->_character == temp_character)
		{
			return temp_node_2;
		}
		return nullptr;
	}

	//根据编码深度优先搜索,同时只要叶子结点
	node* depth_first_search(node* temp_node, string temp_code)
	{
		node* temp_node_1, * temp_node_2;
		if (temp_node == nullptr)
		{
			return nullptr;
		}
		if (temp_node->_left==nullptr && temp_node->_right == nullptr && temp_node->_code == temp_code)
		{
			return temp_node;
		}
		temp_node_1 = depth_first_search(temp_node->_left, temp_code);
		if (temp_node_1 != nullptr && temp_node_1->_left == nullptr &&
			temp_node_1->_right == nullptr && temp_node_1->_code == temp_code)
		{
			return temp_node_1;
		}
		temp_node_2 = depth_first_search(temp_node->_right, temp_code);
		if (temp_node_2 != nullptr && temp_node_2->_left == nullptr &&
			temp_node_2->_right == nullptr && temp_node_2->_code == temp_code)
		{
			return temp_node_2;
		}
		return nullptr;
	}

public:
	//构造函数,同时也是编码树构建
	encoding_tree(string origin_string)
	{
		//初始化
		_node_number = 0;
		//长度
		int length = (int)origin_string.length();
		//权值数组
		int* weight_list = new int[length];
		//字符数组
		char* character_list = new char[length];
		//赋值
		for (int x = 0; x < length; x++)
		{
			character_list[x] = origin_string[x];
		}
		//去除重复字符
		for (int x = 0; x < length; x++)
		{
			weight_list[x] = 1;
			for (int y = x + 1; y < length; y++)
			{
				if (character_list[y] == character_list[x])
				{
					weight_list[x]++;
					erase(character_list, length, y);
					y--;
				}
			}
		}
		//按照权值从小到大排序
		sort(character_list, weight_list, length);
		//结点数组赋值
		node* node_list = new node[length];
		for (int x = 0; x < length; x++)
		{
			node_list[x]._character = character_list[x];
			node_list[x]._weight = weight_list[x];
		}
		//构造树
		//如果只有一个结点
		if(length == 1)
		{
			_node_list[_node_number] = node_list[0];
			node_list[0]._left = &_node_list[_node_number];
			node_list[0]._weight = weight_list[0];
			node_list[0]._character = '#';
			_node_number++;
		}
		while (length != 1)
		{
			_node_list[_node_number] = node_list[0];
			_node_list[_node_number + 1] = node_list[1];
			node_list[0]._left = &_node_list[_node_number];
			node_list[0]._right = &_node_list[_node_number + 1];
			node_list[0]._weight = weight_list[0] + weight_list[1];
			node_list[0]._character = '#';
			weight_list[0] += weight_list[1];
			_node_number += 2;
			erase(node_list, length, 1);
			length++;
			erase(weight_list, length, 1);
			sort(node_list, weight_list, length);
		}
		_node_list[_node_number] = node_list[0];
		_node_number++;
		//设置编码
		set_code(&_node_list[_node_number-1], "");
		//回收内存
		delete []weight_list;
		delete []character_list;
		delete []node_list;
	}
	//析构函数,清理内存
	~encoding_tree()
	{
		delete []_node_list;
	}

	//根据字符串输出编码
	string to_code(string character_list)
	{
		string code_list;
		for (int x = 0; x < character_list.length(); x++)
		{
			node* temp_node = depth_first_search(&_node_list[_node_number - 1], character_list[x]);
			code_list.append(temp_node->_code);
		}
		return code_list;
	}
	
	//根据编码还原字符串
	string to_sentence(string code)
	{
		string temp_sentence;
		while(!code.empty())
		{
			for (int x = 1; x <= code.length(); x++)
			{
				node* temp_node = depth_first_search(&_node_list[_node_number - 1], code.substr(0, x));
				if (temp_node != nullptr)
				{
					temp_sentence.push_back(temp_node->_character);
					code.erase(0, x);
					break;
				}
			}
		}
		return temp_sentence;
	}

	//测试函数,展示整棵树
	void test_show(node* temp_node, int x)
	{
		if (x == 0)
		{
			temp_node = &_node_list[_node_number - 1];
		}
		if (temp_node == nullptr)
		{
			return;
		}
		cout << temp_node->_character << " " <<
			temp_node->_weight << " " << temp_node->_code << endl;
		test_show(temp_node->_left,x+1);
		test_show(temp_node->_right,x+1);
	}
};

测试程序:

#include <iostream>

#include "encoding_tree.h"

using namespace std;

int main(void)
{
	cout << "请在下面输入一段英文:" << endl;
	string sentence;
	getline(cin, sentence);

	if(sentence.length() == 0)
	{
		cout << "输入句子为空,程序结束!" << endl;
		return 0;
	}

	encoding_tree instance_encoding_tree(sentence);

	//测试函数,展示树的全貌
	//instance_encoding_tree.test_show(nullptr,0);

	string code = instance_encoding_tree.to_code(sentence);
	cout << "这段文字的编码为:" << endl;
	cout << code << endl;

	string restored_sentence = instance_encoding_tree.to_sentence(code);
	cout << "编码再还原成文字为:" << endl;
	cout << restored_sentence << endl;

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值