#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());
}
Huffman树,Huffman编码与解码
最新推荐文章于 2023-05-11 20:39:59 发布