压缩软件:
给定一篇文章,只含有英文大小写字母和空格,以.txt格式存储,统计该文件中各种字符的频率,对各字符进行Huffman编码,将该文件翻译成Huffman编码文件,再将Huffman编码文件翻译成源文件。
创建结构体数组,数组的每个元素存有字符,频率,父节点下边,左右孩子的下标。假设有n个结点,先统计每个字符出现的频率当做权值,找出两个权值最小的下标,权值的和作为新的下标存在结构体数组中,遍历n-1次,得到哈夫曼树。从叶结点出发,一直找父节点,直至父节点为根(即par = 0),左边为0,右边为1,得到哈夫曼编码;解码 时按位读取,有映射关系直接输出,否则继续向后读取。
#include <bits/stdc++.h> using namespace std; map<char, int>M; map<char, string>M1; const int N = 500; char s[N]; struct node { int weight, par, l, r; char c; }; //找两个最小权的下标min1, min2 void select(node *Htree, int m, int &min1, int &min2) { min1 = min2 = 0; Htree[0].weight = 1e9; for(int i = 1; i <= m; i++) { if(!Htree[i].par && Htree[i].weight < Htree[min1].weight) min1 = i; } Htree[min1].par = -1; for(int i = 1; i <= m; i++) { if(!Htree[i].par && Htree[i].weight < Htree[min2].weight) min2 = i; } } //创建哈夫曼树 void H_tree(node *Htree, int n) { int min1 = 0, min2 = 0; int now = n+1, m = n;//now是新节点的下标,m是寻找的上限 for(int i = 1; i < n; i++) { select(Htree, m, min1, min2);//在[1,m]中找两个最小权的下标组成now Htree[now].weight = Htree[min1].weight + Htree[min2].weight; Htree[now].l = min1, Htree[now].r = min2; Htree[min1].par = now, Htree[min2].par = now; now++; m++; } } //打印树 //void print(node *t,int next) //{ // printf("%d ",t[next].weight); // if(t[next].l) // print(t, t[next].l); // if(t[next].r) // print(t, t[next].r); //} //进行哈夫曼编码 void encode(node *Htree, int n, int len) { char temp[N];//临时存放某个叶子节点的哈夫曼编码 int now = N-1; //逆序推出哈夫曼编码,左边为0,右边为1 temp[now] = '