Huffman Coding

本文详细介绍了Huffman编码的原理及其在文本压缩中的应用,通过实例展示了如何计算最优编码长度,并提供了实现算法的代码片段。此外,文章还讨论了编码的唯一性及其在实际场景中的优化策略。

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

Description

美国数学家David Huffman1952年发明了赫夫曼编码,在编码中用到的特殊的二叉树称为Huffman tree

给出n个字符在文本中的出现次数,输出文本的Huffman编码长度(即编码后的二进制序列有多少位)。

例如,5个字符出现的次数如下,采用对应Huffman编码可得到最优编码长度为4×5+3×15+1×40+2×30+4×10=205。

对应的Huffman Tree如下:

Input

输入的第1行是字符个数n(0<n<=52);以下n行每行为一个字符c及其出现的次数w(c),之间用一个空格分隔。字符只可能为大小写英文字母,输入保证n个字符各不相同。

Output

 单独一行输出Huffman编码长度。

Sample Input
Copy sample input to clipboard
5
A 5
B 15
C 40
D 30
E 10
Sample Output
205

// 编码不唯一
#include <iostream>
#include <deque>
#include <algorithm>
#include <string> 
using namespace std;

string str = "";
int sum = 0;
//int sequence = 1;
struct Node
{
	int value;
	char ch;
	Node *left;
	Node *right;
	//int order; 
} *ptr, node[100];
void inorder(Node *sub_root)  // 后序遍历
{
	if (sub_root != NULL) {
		str += '0'; 
		inorder(sub_root->left);
		int len1 = str.length() - 1;
		str.erase(len1);
		str += '1';
		inorder(sub_root->right);
		int len2 = str.length() - 1;
		str.erase(len2);
		if (sub_root->ch != '@') {
			cout << sub_root->ch << " " << str << endl;
			sum += sub_root->value * len2;
		}
	}
}
deque<Node*> forest;

bool compare(Node *a, Node *b)
{
	return a->value <= b->value;
}
bool cmp(Node a, Node b)
{
	return a.value < b.value;
}
int frequency[100] = {0};
char words[100];

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		ptr = new Node;
		cin >> node[i].ch >> node[i].value;
		ptr->ch = node[i].ch;
		ptr->value = node[i].value;
	//	ptr->order = 0;
		ptr->left = NULL;
		ptr->right = NULL;
		forest.push_back(ptr);
	}
//	deque<Node*>::iterator iter;
	//sort(node, node + n, cmp);
	for (int i = 0; i < n - 1; i++)
	{
		stable_sort(forest.begin(),forest.end(),compare);
		/*for (iter = forest.begin(); iter != forest.end(); iter++)
		{
			cout << (*iter)->ch << (*iter)->value << " ";
		}
		cout << endl;*/
		ptr = new Node;
		ptr->value = forest[0]->value + forest[1]->value;
		/*if (forest[0]->value < forest[1]-> value || forest[0]->order <= forest[1]->order) {
			ptr->left = forest[0];
			ptr->right = forest[1];
		} else {
			ptr->left = forest[1];
			ptr->right = forest[0];
		}*/
		ptr->left = forest[0];
		ptr->right = forest[1];
		ptr->ch = '@';
	//	ptr->order = sequence++;
		forest.pop_front();
		forest.pop_front();
		forest.push_back(ptr);
	}
	//ptr = forest.front();
	 
	inorder(ptr);
	cout << "sum of bits: " << sum << endl;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值