哈夫曼编码与解码

本文深入探讨了哈夫曼编码的概念,详细解释了如何构建哈夫曼树以及进行编码和解码的过程。通过实例展示了哈夫曼编码如何有效压缩数据,并讨论了其在数据传输和存储中的应用。
摘要由CSDN通过智能技术生成

哈夫曼编码与解码

#include<iostream>
#include<queue>
#include<string>
using namespace std;

class Node {
public:
	char c; 
	int frequency;//出现频率
	Node* left;
	Node* right;
	Node() {};
	Node(char c1,int f,Node* l=NULL,Node* r=NULL ):c(c1),frequency(f),left(l),right(r){} //构造函数
	bool operator<(const Node& node)const { //使优先队列按频率从小到大排
		return frequency > node.frequency;
	}
	void code(priority_queue<Node>& q); //编码函数
	void decode(priority_queue<Node>& q1,string s); //解码函数
};

void Node::code(priority_queue<Node>& q) //编码函数,构建哈夫曼树
{
	while (q.size() != 1) { //不断循环直到优先队列中只有一个元素
		Node *left = new Node(q.top()); //取出队列首元素,频率小的放左边
		q.pop(); //删除此元素
		Node *right = new Node(q.top()); //频率大的放右边
		q.pop(); //删除此元素
		Node node('R', left->frequency + right->frequency, left, right);  //创建新节点,频率为上述两者的和
		q.push(node); //将新元素加入到优先队列中,仍按频率从小到大的顺序
	}
}

void Node::decode(priority_queue<Node>& q1,string s) //解码函数,往左为0,往右为1
{	
	Node n = q1.top(); //取出经编码的哈夫曼树的根节点
	Node* n1 = &n; //将Node类型的根节点转换为Node*类型
	Node* n2 = &n; //备份原根节点
	if (n.left == NULL && n.right == NULL) //当哈夫曼树中仅有一个元素时,直接输出
		cout << "树中只有一个元素:" << n.c << endl;

	else { //哈夫曼树中大于两个元素时,因为不存在只有两个节点的情况
		for (int i = 0; i < s.size(); i++) { //对输入的一串01序列进行遍历
			if (s[i] != '0'&&s[i] != '1') { //如果输入了除0 1以外的字符则报错
				cout << "输入错误" << endl;
				break;
			}
			while (1) {
				if (s[i] == '0') { //当遇到0时,往左子树找
					n1 = n1->left; //指针指向左孩
					if (n1->c == 'R') { //不是叶子时,直接跳出循环
						break;
					}
					if (n1->c != 'R') { //是叶子时,输出所解码的字符
						cout << n1->c; 
						n1 = n2; //指针指回哈夫曼树的根节点,再跳出循环
						break;
					}
				}
				else if (s[i] == '1'){ //当遇到1时,往右子树找
					n1 = n1->right; //指针指向右孩
					if (n1->c == 'R') { //不是叶子时,直接跳出循环
						break;
					}
					if (n1->c != 'R') { //是叶子时,输出所解码的字符
						cout << n1->c; 
						n1 = n2; //指针指回哈夫曼树的根节点,再跳出循环
						break;
					}
				}
			}
		}
	}
}

int main()
{
	Node x, y;
	Node a('A', 20);
	Node b('B', 10);
	Node c('C', 10);
	Node d('D', 15);
	Node e('E', 45);
	priority_queue<Node> q,q1;
	q.push(a); //A20
	q.push(b); //B10 A20
	q.push(c); //B10 C10 A20
	q.push(d); //B10 C10 D15 A20
	q.push(e); //B10 C10 D15 A20 E45

	q1.push(a); //A20
	y.code(q1);
	string s1="0";
	y.decode(q1, s1); //考虑当树中只有一个节点时

	x.code(q);
	while (1) {
		string s0;
		cout << endl << "请输入一串编码" << endl;
		cin >> s0;
		x.decode(q, s0);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值