哈弗曼編碼可以實現一個文本的壓縮編碼,現有一個字符串代表文本內容,請問此文本經過哈弗曼編碼後的大小是多少字節。
如:“aabc”
建立一棵哈弗曼樹可知上述字符串中的字符的編碼
a:1
b:00
c:01
因此,“aabc”的哈弗曼編碼爲“110001”,共六個字節。
代碼如下:
#include <iostream>
using namespace std;
char str[30]; //輸入的字符
struct Node
{
Node *lchild;
Node *rchild;
char c; //字符
int value; //字符出現的頻率
bool operator < (Node &A)
{
return value < A.value;
}
}TreeNode[50];
int loc;
Node *creat() //初始化
{
TreeNode[loc].lchild = NULL;
TreeNode[loc].rchild = NULL;
TreeNode[loc].c = NULL;
TreeNode[loc].value = 0;
return &TreeNode[loc++];
}
Node *deleteNode()
{
TreeNode[loc].lchild = NULL;
TreeNode[loc].rchild = NULL;
TreeNode[loc].c = NULL;
TreeNode[loc].value = 0;
return &TreeNode[--loc];
}
void structOriginal() //記錄輸入字符串中每個字符出現的頻率,初始化結點
{
int len = strlen(str);
for (int i = 0; i < len; i++)
{
Node *T = NULL;
if (T==NULL)
{
T = creat();
T->c = str[i];
T->value += 1;
}
for (int j = 0; j < len; j++)
{
if (j<i && T->c==str[j])
{
T = deleteNode();
break;
}
else if (j>i && T->c==str[j])
{
T->value += 1;
}
}
}
}
int rankTreeNode() //給結構數組排序,按權值;loc記錄了當前結點個數
{
int tree_n = loc;
for (int i = 0; i < loc-1; i++)
{
bool flag = false;
for (int j = loc-1; j > i; j--)
{
if (TreeNode[j] < TreeNode[j - 1])
{
swap(TreeNode[j].value, TreeNode[j - 1].value);
swap(TreeNode[j].c, TreeNode[j - 1].c);
flag = true;
}
}
if (flag==false)
{
return tree_n;
}
}
return tree_n;
}
//按結點權值構造一棵哈弗曼樹
Node *buildHuffmanTree(Node *T,int n) //n表示當前最大權值結點的位置
{
int count = 0;
for (int index = 0; index < n; index++)
{
count += TreeNode[index].value;
}
if (T==NULL)
{
T = creat();
T->value = count;
if (n == 1)
{
return T;
}
else
{
T->rchild = &TreeNode[--n];
T->lchild = buildHuffmanTree(T->lchild, n);
}
}
return T; //返回根結點指針
}
int main()
{
int str_n; //結點個數
while (cin>>str_n)
{
loc = 0;
Node *T = NULL; //哈弗曼樹根結點爲空
cin >> str;
structOriginal();
int tree_count = rankTreeNode(); //tree_count是除去重複的結點,實際參與排序的結點個數
T = buildHuffmanTree(T, tree_count); //哈弗曼樹的根結點
int tree_length = 0; //樹高
int ret = 0; //結果
while (T->rchild!=NULL)
{
tree_length++;
ret += tree_length*(T->rchild)->value;
T = T->lchild;
}
ret += tree_length*(T->value);
cout << ret << endl;
}
return 0;
}
粗略的碼了一下,不太完善的地方請大家指正。