版权声明:转载请注明出处 https://blog.csdn.net/Hpuer_Random/article/details/83546658
实现一个哈夫曼编码系统,系统包括以下功能:
- 字符信息统计:读取待编码的源文件SourceFile.txt,统计出现的字符及其频率。
- 建立哈夫曼树:根据统计结果建立哈夫曼树。
- 建立哈夫曼码表:利用得到的哈夫曼树,将各字符对应的编码表保存在文件Code.txt中。
- 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile.txt。
SourceFile.txt 的文件内容为:
要对下边的字符进行哈夫曼编码处理
AAAAABBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCDDDDDDDDEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFGGGHHHHHHHHHHH
出现的字符及其频率
A:5
B:25
C:7
D:8
E:14
F:21
G:3
H:11
哈夫曼树
i weight parent lchild rchild
1 5 10 0 0
2 25 14 0 0
3 7 9 0 0
4 8 10 0 0
5 14 13 0 0
6 21 12 0 0
7 3 9 0 0
8 11 12 0 0
9 10 11 3 7
10 13 11 4 1
11 23 13 10 9
12 32 14 6 8
13 37 15 11 5
14 57 15 12 2
15 94 0 14 13
各字符对应的编码表 即文件Code.txt
i Char Code
1 A 0110
2 B 10
3 C 0101
4 D 0111
5 E 00
6 F 111
7 G 0100
8 H 110
得到的文件ResultFile.txt内容为
01100110011001100110101010101010101010101010101010101010101010101010100101010101010101010101010101011101110111011101110111011101110000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111010001000100110110110110110110110110110110110
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e3+7;
typedef char **HuffmanCode;
typedef struct{
int weight;
int parent, lchild, rchild;
}HTNode,*HuffmanTree;
HuffmanTree HT;
HuffmanCode HC;
int m,s1,s2,start,c,f;
char *cd;
int z[30];
void Select(HuffmanTree HT,int n,int &s1,int &s2)//Select函数
{
int min1 = 0x3f3f3f3f;
int min2 = 0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
if(HT[i].parent) continue;//if this node's parent not equal zero,it not root;
if(HT[i].weight < min1)
{
min1 = HT[i].weight;
s1 = i;
continue;
}
if(HT[i].weight < min2 && HT[i].weight >= min1)
{
min2 = HT[i].weight;
s2 = i;
}
}
}
void GreatHuffmanTree(HuffmanTree &HT, int n)//建立哈夫曼树
{
if(n<=1) return ;
m = 2*n - 1;
HT = new HTNode[m+1];
for(int i=1; i<=m; ++i)
HT[i].parent = HT[i].lchild = HT[i].rchild = 0;
for(int i=1; i<=n; ++i)//需要更改
HT[i].weight=z[i];
for(int i=n+1; i<=m; ++i)
{
Select(HT,i-1,s1,s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n)
{
HC = new char*[n+1];
cd = new char[n];
cd[n-1] = '\0';
for(int i=1; i<=n; ++i)
{
start = n-1;
c = i;
f = HT[i].parent;
while(f!=0)//
{
--start;
if(HT[f].lchild == c) cd[start]='0';
else cd[start]='1';
c = f;
f = HT[f].parent;//向上回溯
}
HC[i] = new char[n-start];
strcpy(HC[i],&cd[start]);
}
delete cd;
}
int main()
{
// freopen("in.txt", "r", stdin);//文件要和代码放在同一个文件夹
// freopen("out.txt", "w", stdout);
char s[MAXN];
scanf("%s",s);
int len = strlen(s);
memset(z,0,sizeof(z));
for(int i=0;i<len;i++)//统计字符个数
z[s[i]-'A'+1]++;
int cnt=0;
for(int i=1;i<=26;++i)
if(z[i])
cnt++;
for(int i=1;i<=26;i++)
if(z[i])
printf("%c:%d\n",'A'+i-1,z[i]);
GreatHuffmanTree(HT,cnt);
//输出一下看看是否建立好哈夫曼数
printf("\n i weight parent lchild rchild \n");
for(int i=1; i<=m; ++i)
printf("%2d %5d %8d %8d %8d\n",i,HT[i].weight,HT[i].parent,HT[i].rchild,HT[i].lchild);
CreatHuffmanCode(HT,HC,cnt);
printf("\n\nHuffmanCode:\n");
printf(" i Char Code\n\n");
for(int i=1; i<=cnt; ++i)
printf("%2d %c %s\n",i,i+'A'-1,HC[i]);
puts("");
for(int i=0;i<len;i++)
printf("%s",HC[s[i]-'A'+1]);
return 0;
}