一、实验目的
1、熟练掌握哈夫曼树的生成算法。
2、熟练掌握哈夫曼编码的方法。
二、实验内容
[问题描述]
已知n个字符在原文中出现的频率,求它们的哈夫曼编码。
[基本要求]
1. 初始化:从键盘读入n个字符,以及它们的权值,建立Huffman
树。(
2. 编码:根据建立的Huffman树,求每个字符的Huffman编码。
对给定的待编码字符序列进行编码。
[选作内容]
1. 译码:利用已经建立好的Huffman树,对上面的编码结果译码。
译码的过程是分解电文中的字符串,从根结点出发,按字符’0’和’1’确定找左孩子或右孩子,直至叶结点,便求得该子串相应的字符。
4. 打印 Huffman树。
[测试数据]
利用教材P136 例5.3中的数据调试程序(也可自己设定数据进行测试)。
三、实验前的准备工作
1、掌握树的逻辑结构。
2、掌握哈夫曼树的定义及生成算法。
3、掌握哈夫曼编码的方法。
四、实验报告要求
1、实验报告要按照实验报告格式规范书写。
2、实验上要写出多批测试数据的运行结果。
3、结合运行结果,对程序进行分析。
#include <iostream>
#include <queue>
#include <vector>
#include <string>
using namespace std;
struct HuffmanNode {
char data; // 字符
int weight; // 权值
HuffmanNode* left; // 左子树指针
HuffmanNode* right; // 右子树指针
HuffmanNode(char d, int w): data(d), weight(w), left(NULL), right(NULL) {}
};
struct CompareHuffmanNode {
bool operator()(const HuffmanNode* a, const HuffmanNode* b) {
return a->weight > b->weight;
}
};
HuffmanNode* generateHuffmanTree(char data[], int weight[], int n) {
priority_queue<HuffmanNode*, vector<HuffmanNode*>, CompareHuffmanNode> pq;
for (int i = 0; i < n; i++) {
pq.push(new HuffmanNode(data[i], weight[i]));
}
while (pq.size() > 1) {
HuffmanNode* left = pq.top();
pq.pop();
HuffmanNode* right = pq.top();
pq.pop();
HuffmanNode* parent = new HuffmanNode('\0', left->weight + right->weight);
parent->left = left;
parent->right = right;
pq.push(parent);
}
return pq.top();
}
void generateHuffmanCode(HuffmanNode* root, string code, vector<string>& codes) {
if (root ==NULL) {
return;
}
if (root->data != '\0') {
codes[root->data] = code;
}
generateHuffmanCode(root->left, code + "0", codes);
generateHuffmanCode(root->right, code + "1", codes);
}
int main() {
int n;
cout << "请输入字符个数:";
cin >> n;
char data[n];
int weight[n];
cout << "请输入字符和对应权值:" << endl;
for (int i = 0; i < n; i++) {
cin >> data[i] >> weight[i];
}
HuffmanNode* root = generateHuffmanTree(data, weight, n);
vector<string> codes(128, ""); // 存储每个字符的哈夫曼编码,假设字符的ASCII码范围为0-127
generateHuffmanCode(root, "", codes);
cout << "字符的哈夫曼编码:" << endl;
for (int i = 0; i < n; i++) {
cout << data[i] << ": " << codes[data[i]] << endl;
}
return 0;
}