Huffman树的应用:
1、先选择一篇文章
2、然后统计字符个数
3、对个数不为0字符的进行编码
4、输出码文
5、进行译码
上机代码:
/************************************************************************* > File Name: Huffman树的应用.cpp > Author: zzuspy > Mail: [email protected] > Created Time: 2014年12月3日 14:30 ************************************************************************/ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <stack> #include <queue> #define LL long long #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) using namespace std; typedef struct { int weight; int parent, lchild, rchild; }HTNode, *HuffmanTree; typedef char * * HuffmanCode; int s1, s2; void Select(HuffmanTree &HT, int n) { int i, min; for(int i=1; i<=n; i++) { if(HT[i].parent==0) { min = i; break; } } for(i=1; i<=n; i++) { if(HT[i].weight<HT[min].weight && HT[i].parent == 0)min = i; } s1 = min; for(int i=1; i<=n; i++) { if(HT[i].parent==0 && i!=s1) { min = i; break; } } for(int i=1; i<=n; i++) { if(HT[i].parent == 0 && i!=s1 && HT[i].weight<HT[min].weight && HT[i].weight>=HT[s1].weight) min=i; } s2 = min; } void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n) { if(n<=1) return; int m = 2 * n - 1, i; HuffmanTree p; HT = (HuffmanTree)malloc( (m + 1) * sizeof(HTNode)); for( p = HT+1, i = 1; i <= n; i++, p++, w++) { p->weight = *w; p->parent = p->lchild = p->rchild = 0; } for(; i <= m; i++, p++) { p->weight = p->parent = p->lchild = p->rchild = 0; } //输出这时Huffman树 /*for(int i=1; i<=n; i++) { printf("%d %d %d %d\n", HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild); }*/ for(i = n + 1; i<=m; i++) { Select(HT, i-1); //printf("%d %d\n", 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; } HC = (HuffmanCode)malloc( ( n + 1 ) * sizeof(char *)); char *cd = (char *)malloc( n * sizeof(char) ); cd[n-1] = '\0'; for(i=1; i<=n; i++) { int start = n - 1; for(int c = i, f = HT[i].parent; f!=0; c=f, f=HT[f].parent) if(HT[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; HC[i] = (char*)malloc( (n-start) * sizeof(char)); strcpy(HC[i], &cd[start]); } free(cd); } void mawen(HuffmanCode &HC, char str[]) { printf("\n\n"); FILE *p; char c; p = fopen("essay","r"); while((c = fgetc(p))!=EOF) { for(int i=0; str[i]!='\0'; i++) { if(str[i] == c) { printf("%c %s ", c, HC[i+1]); break; } } } fclose(p); printf("\n\n"); } void codetext(char wen[], HuffmanCode &HC, char str[]) { int start = 0; FILE *p; char c; p = fopen("essay","r"); while((c = fgetc(p))!=EOF) { for(int i=0; str[i]!='\0'; i++) { if(str[i] == c) { strcpy(wen+start, HC[i+1]); start+=strlen(HC[i+1]); break; } } } fclose(p); printf("\n\n"); } void translate(char wen[], int wei[], char str[], HuffmanTree &HT, HuffmanCode &HC, int elem) { int q = 2 * elem - 1, n=0; char *ch; ch = (char*)malloc(100*sizeof(char)); for(int i=0; wen[i]!='\0'; i++) { if(wen[i] == '0') { *(ch+n) = '0'; *(ch+n+1) = '\0'; n++; q = HT[q].lchild; if(HT[q].rchild==0 && HT[q].lchild==0) { int i; for(i=0; i<elem; i++) { if(!strcmp(ch, HC[i+1]))break; } printf("%c", str[i]); q = 2 * elem - 1; n = 0; } } else if(wen[i] == '1') { *(ch+n) = '1'; *(ch+n+1) = '\0'; n++; q = HT[q].rchild; if(HT[q].rchild==0 && HT[q].lchild==0) { int i; for(i=0; i<elem; i++) { if(!strcmp(ch, HC[i+1]))break; } printf("%c", str[i]); q = 2 * elem - 1; n = 0; } } } } int wei[128]; //保存字符数大于0的每个字符的数目 (即权值) char str[128]; //保存字符数大于0的字符 int elem = 0; //统计后字符数大于0的字符的总数 int statis[128]; //统计文章中各种字符的数目 char wen[1000010]; //用于保存码文 int main() { //打开文件读取字符,再统计每个字符的个数 FILE *p; char c; p = fopen("essay","r"); while((c = fgetc(p))!=EOF) { printf("%c", c); //输出文章 statis[c]++; } fclose(p); //输出统计后个数大于0的字符 /*for(int i=0; i<128; i++) { if(statis[i]!=0) printf("%c : %d ", i, statis[i]); }*/ //压缩字符,去掉字符数为0的字符 for(int i=0; i<128; i++) { if(statis[i]!=0) { str[elem] = i; wei[elem] = statis[i]; elem++; } } //输出压缩后字符及其个数 /*for(int i=0; i<elem; i++) { printf("%c : %d ", str[i], wei[i]); }*/ //printf("\n%d\n", elem); //个数大于0的字符总数 HuffmanTree HT; HuffmanCode HC; //调用Huffman函数 ,将每个字符对应的编码存在HC里,HT为你所建立的Huffman树 HuffmanCoding(HT, HC, wei, elem); //输出构造的Huffman树 /*for(int i=1; i<=2*elem-1; i++) { printf("%d %d %d %d %d\n", i, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild); }*/ //输出个数大于0的字符及其字符编码 /*for(int i=1; i<=elem; i++) { printf("\n%c %s\n", str[i-1], HC[i]); }*/ printf("\n\n"); //调用码文函数 mawen(HC, str); printf("\n\n"); //生成码文 codetext(wen, HC, str); //printf("%s\n", wen); //译文 translate(wen, wei, str, HT, HC, elem); return 0; }
时间: 2024-10-05 23:19:18