数据结构—HuffmanTree
实验目的:
1.掌握二叉树的定义;
2.掌握哈夫曼树和哈夫曼编码算法的实现。
实验内容:
实现一个哈夫曼编码系统,系统包括以下功能:
(1) 字符信息统计:读取待编码的源文件SourceFile.txt,统计出现的字符及其频率。
(2) 建立哈夫曼树:根据统计结果建立哈夫曼树。
(3) 建立哈夫曼码表:利用得到的哈夫曼树,将各字符对应的编码表保存在文件Code.txt中。
(4) 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile.txt。
随机样例生成器:
#include <bits/stdc++.h>
using namespace std;
int Random(int start, int end){ //字符ASCLL码的区间
int dis = end - start;
return rand() % dis + start;
}
int main() {
FILE *fp ;
fp = fopen("SourceFile.txt" ,"a" );
for (int i = 1 ; i <= 100 ; i ++ ) { // i 样例的组数,可以自行调整
int lenght = 100; // 样例的长度 ,可以自行调整
for (int j = 1 ; j <= lenght ; j ++ ) {
fprintf(fp , "%c" , Random(65 ,90 )) ;
} fprintf(fp , "\n") ;
}
fclose(fp) ;
return 0;
}
HuffmanTree code :
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 50 ;
typedef char **HuffmanCode;
typedef struct Node
{
int weight;
int parent ,lchild ,rchild ;
}HTNode ,*HuffmanTree ;
int weight[maxn] ;
char str[maxn] ;
map<char ,int >mp ;
map<int ,char >mmp;
void Select(HuffmanTree HT ,int pos ,int &s1 ,int &s2 ) {
int min1 = 0x3f3f3f3f ,min2 = 0x3f3f3f3f ;
for (int i = 1 ; i <= pos ; i ++ ) {
if ( !HT[i].parent && min1 > HT[i].weight) {
min1 = HT[i].weight; s1 = i;
}
}
HT[s1].parent = 1;
for (int i = 1 ; i <= pos ; i ++ ) {
if ( !HT[i].parent && min2 > HT[i].weight ) {
min2 = HT[i].weight; s2 = i ;
}
}
}
void CreatHuffmanTree(HuffmanTree &HT ,int n ) {
if ( n <= 1 ) return;
int m = 2 * n ;
HT = new HTNode[m+1] ;
for (int i = 1 ; i <= m ; i ++ ) {
HT[i].parent = HT[i].lchild = HT[i].rchild = HT[i].weight = 0;
}
for (int i = 1 ; i <= n ; i ++ ) {
HT[i].weight = weight[i] ;
}
int s1 ,s2 ;
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 ) {
char *cd ;
int start ,c ,f ;
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() {
FILE *fp , *filestream ;
fp = fopen("SourceFile.txt" ,"r" );
for (int k = 1 ; k <= 100 ; k ++ ) {
mp.clear(); mmp.clear();
fgets(str + 1 ,maxn ,fp) ;
int len = strlen(str + 1) ;
int cnt = 0;
for (int i = 1 ; i <= len - 1 ; i ++ ) {
if ( !mp[str[i]] ) {
mp[str[i]] = ++cnt ;
mmp[cnt] = str[i] ;
}
weight[cnt] ++;
}
HuffmanTree HT; HuffmanCode HC ;
CreatHuffmanTree(HT ,cnt );
// for (int i = 1 ; i <= cnt * 2 - 1 ; i ++ ) {
// printf("i = %d, mp[str[i]] = %c,HT[i].parent = %d,HT[i].weight = %d,HT[i].lchild = %d,HT[i].rchild = %d\n",i ,mmp[i] ,HT[i].parent,HT[i].weight ,HT[i].lchild ,HT[i].rchild );
// }
CreatHuffmanCode(HT ,HC ,cnt ) ;
filestream = fopen("ResultFile.txt" , "a");
fprintf(filestream ,"第%d组样例结果\n" ,k );
for (int i = 1 ; i <= cnt ; i ++ ) {
int len1 = strlen(HC[i]);
fprintf(filestream ,"%c : ",mmp[i]) ;
for (int j = 1 ; j <= len1 ; j ++ ) {
fprintf(filestream ,"%c" ,HC[i][j] );
} fprintf(filestream ,"\n" ) ;
}
fprintf(filestream ,"第%d组样例结束\n" ,k );
}
fclose(filestream);
fclose(fp) ;
return 0;
}