哈夫曼编码和译码

哈夫曼编码和译码

#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
*/
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值