哈夫曼樹——————資料結構作業
阿新 • • 發佈:2018-11-07
實現一個哈夫曼編碼系統,系統包括以下功能:
- 字元資訊統計:讀取待編碼的原始檔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;
}