哈夫曼编码和译码
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<iomanip>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
#define Binarytree_malloc (Binarytreepointer)malloc(sizeof(Binarytree))
using namespace std;
typedef struct Binarytree{
int data;
char ch;
Binarytree *leftson, *rightson;
void leaf_create(char ch) {
this->ch = ch;
cin >> data;
leftson = nullptr;
rightson = nullptr;
}
void father_create(Binarytree *leftson, Binarytree *rightson) {
this->leftson = leftson;
this->rightson = rightson;
this->data = leftson->data + rightson->data;
}
} Binarytree, *Binarytreepointer;
struct Binarytreepointer_cmp{
bool operator() (const Binarytreepointer a, const Binarytreepointer b) const{
return (a->data) > (b->data);
}
};
queue<char> leaf_ch;
map<char, string> huffman_codes_map;
priority_queue<Binarytreepointer, vector<Binarytreepointer>, Binarytreepointer_cmp> heap_sort;
void read_leafnode() {
int n;
cin >> n;
while(n--) {
char ch;
cin >> ch;
Binarytreepointer leafnode = Binarytree_malloc;
leafnode->leaf_create(ch);
leaf_ch.push(ch);
heap_sort.push(leafnode);
}
}
Binarytreepointer huffman_bulid() {
Binarytreepointer left_son = heap_sort.top(); heap_sort.pop();
if(heap_sort.empty()) return left_son;
Binarytreepointer right_son = heap_sort.top(); heap_sort.pop();
Binarytreepointer father = Binarytree_malloc;
father->father_create(left_son, right_son);
heap_sort.push(father);
return huffman_bulid();
}
pair<int, int> get_huffman_codes(Binarytreepointer root, string prefix) {
if(root->leftson) {
pair<int, int> left_average_coding_length = get_huffman_codes(root->leftson, prefix + "0");
pair<int, int> right_average_coding_length = get_huffman_codes(root->rightson, prefix + "1");
return make_pair(left_average_coding_length.first+right_average_coding_length.first, left_average_coding_length.second+right_average_coding_length.second);
}
huffman_codes_map[root->ch] = prefix;
return make_pair(root->data * prefix.size(), root->data);
}
void print_huffman_codes(Binarytreepointer root) {
pair<int, int> average_coding_length = get_huffman_codes(root, "");
cout << "编码为:" << endl;
while(!leaf_ch.empty()) {
char ch = leaf_ch.front(); leaf_ch.pop();
cout << ch << " " << huffman_codes_map[ch] << endl;
}
cout << "平均编码长度: " << setw(2) << average_coding_length.first * 1.0 / average_coding_length.second << endl;
huffman_codes_map.clear();
}
void decode_huffman_codes(string key, Binarytreepointer root) {
cout << "对应的编码为: ";
for(int i = 0; ; ) {
if(key[i] == '#') break;
else {
Binarytreepointer current = root;
while(current->leftson) {
if(key[i++] == '0') current = current->leftson;
else current = current->rightson;
}
cout << current->ch;
}
}
cout << endl;
}
void huffman_destroy(Binarytreepointer current) {
if(current->leftson) {
huffman_destroy(current->leftson);
huffman_destroy(current->rightson);
}
free(current);
}
int main() {
string key;
read_leafnode();
/*
检验heap_sort正确性
while(!heap_sort.empty()) {
cout << heap_sort.top()->data << endl;
heap_sort.pop();
}
*/
cin >> key;
Binarytreepointer huffman_root = huffman_bulid();
print_huffman_codes(huffman_root);
decode_huffman_codes(key, huffman_root);
huffman_destroy(huffman_root);
return 0;
}
/*
Sample Input:
5
A 8
B 20
C 30
D 15
E 27
0101101110#
Sample Output:
编码为:
A 010
B 00
C 11
D 011
E 10
平均编码长度: 2.23
对应的编码为: ACDE
*/