Huffman树,Huffman编码与解码

#include<iostream>
#include<string>
#include<iomanip>
#include<algorithm>
#include<deque>
#include<stack>
#include<list>
#include<queue>
using namespace std;
struct node
{
	int parent;
	int lchild;
	int rchild;
	int weight;
};
struct huffcode
{
	char data;
	string  code;
};
class huffman_tree
{
private:
	node* tree;
	huffcode* huffman_codetable;
	char str[1024];
	char leaf[256];
	int sum_num[256];
	void code(int i, string oldcode);
public:
	int n;//叶子节点的个数
	void Init();//可对输入的string进行统计每个字符出现的频率
	void Creathuffman_tree();//创建huffman树
	void smin(int& x, int& y, int s, int e);
	void CreatTable();//利用已经创建好的huffman树进行编码,并将每个字符的编码输出
	string  Encoding();//对输入字符串进行编码,输出编码后的字符串
	int  Decoding(string gggggggg);//译码
	void Print(int i, int m);//打印huffman树
	void print_code_table();
	~huffman_tree();//析构
};
void huffman_tree::Init()
{
	int str_char_num[256] = { 0 };
	int ch = cin.get();
	int i = 0;
	while ((ch != '\r') && (ch != '\n'))
	{
		str_char_num[ch]++;
		str[i++] = ch;
		ch = cin.get();
	}
	str[i] = '\0';
	n = 0;
	for (int m = 0; m < 256; m++)
	{
		if (str_char_num[m] > 0)
		{
			leaf[n] = (char)m;
			sum_num[n] = str_char_num[m];
			n++;
		}
	}
}
void huffman_tree::Creathuffman_tree()
{

	huffman_codetable = new huffcode[n];
	tree = new node[2 * n - 1];
	for (int i = 0; i < n; i++)
	{
		tree[i].weight = sum_num[i];
		tree[i].lchild = -1;
		tree[i].rchild = -1;
		tree[i].parent = -1;
		huffman_codetable[i].data = leaf[i];
	}
	int x, y;
	for (int i = n; i < 2 * n - 1; i++)
	{
		smin(x, y, 0, i);
		tree[x].parent = i;
		tree[y].parent = i;
		tree[i].weight = tree[x].weight + tree[y].weight;
		tree[i].lchild = x;
		tree[i].rchild = y;
		tree[i].parent = -1;
	}
}
void huffman_tree::smin(int& x, int& y, int s, int e)
{
	int i;
	for (i = s; i <= e; i++)
		if (tree[i].parent == -1)
		{
			x = y = i;
			break;
		}
	for (; i < e; i++)
		if (tree[i].parent == -1)
		{
			if (tree[i].weight < tree[x].weight)
			{
				y = x;
				x = i;
			}
			else if ((x == y) || (tree[i].weight < tree[y].weight))
				y = i;
		}
}
void huffman_tree::code(int i, string oldcode)
{
	if (tree[i].lchild == -1)
	{
		huffman_codetable[i].code = oldcode;
		return;
	}
	code(tree[i].lchild, oldcode + "0");
	code(tree[i].rchild, oldcode + "1");
}
void huffman_tree::CreatTable()
{
	if (n == 1) {
		code(2 * n - 2, "0");
	}
	else
	{
		code(2 * n - 2, "");
	}
}
void huffman_tree::print_code_table()
{
	for (int i = 0; i < n; i++)
	{
		cout << huffman_codetable[i].data << "   :  " << huffman_codetable[i].code << endl;
	}
}
string huffman_tree::Encoding()
{
	string result = "";
	string gggggg = "";
	for (int gg = 0; gg < strlen(str); gg++)
	{
		gggggg += str[gg];
	}
	for (int i = 0; i <= gggggg.length() - 1; i++)
	{
		char ch = gggggg[i];
		for (int j = 0; j <= n - 1; j++)
		{
			if (huffman_codetable[j].data == ch)
			{
				result += huffman_codetable[j].code;
			}
		}
	}
	return result;
}
int  huffman_tree::Decoding(string x)
{
	int len = x.length(), i;
	int now = 2 * n - 2;

	for (i = 0; i < len; i++)
	{
		if (now == 0)
		{
			cout << huffman_codetable[now].data;
		}
		else
		{

			if (x[i] == '0')
			{
				now = tree[now].lchild;
			}
			else if (x[i] == '1')
			{
				now = tree[now].rchild;
			}
			if (tree[now].lchild == -1 && tree[now].rchild == -1)
			{
				cout << huffman_codetable[now].data;
				now = 2 * n - 2;
			}
		}
	}
	cout << endl;
	if (now == 2 * n - 2)
		return 1;
	return 0;
}
void huffman_tree::Print(int i, int m)
{
	if (tree[i].lchild == -1)
	{
		cout << setfill(' ') << setw(m + 1) << leaf[i] << setfill('-') << setw(10 - m) << '\n';
	}
	else
	{
		cout << setfill(' ') << setw(m + 1) << tree[i].weight << setfill('-') << setw(10 - m) << '\n';
		Print(tree[i].lchild, m + 1);
		Print(tree[i].rchild, m + 1);
	}
}
huffman_tree::~huffman_tree()
{
	delete[]tree;
	delete[]huffman_codetable;
}
int main()
{
	huffman_tree huffman_code;
	cout << "请输入您要写的字符串 :";
	huffman_code.Init();
	cout << "build a huffman tree:" << endl;
	huffman_code.Creathuffman_tree();
	huffman_code.Print(2 * huffman_code.n - 2, 1);
	cout << "build the huffman_code_table :" << endl;
	huffman_code.CreatTable();
	huffman_code.print_code_table();
	cout << "编码结果:" << huffman_code.Encoding() << endl;
	cout << "解码结果:";
	huffman_code.Decoding(huffman_code.Encoding());
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值