哈弗曼編碼,求編碼字節總數

問題描述:
哈弗曼編碼可以實現一個文本的壓縮編碼,現有一個字符串代表文本內容,請問此文本經過哈弗曼編碼後的大小是多少字節。


如:“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;

}


粗略的碼了一下,不太完善的地方請大家指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章