通过读入文件构造哈夫曼树C++
时间: 2023-07-08 11:27:04 浏览: 118
好的,我可以为你解答这个问题。
首先,我们需要了解哈夫曼树的构造过程。哈夫曼树是一种基于字符频率构建的最优二叉树,用于数据压缩和编码。构造哈夫曼树的过程包括以下几个步骤:
1. 统计每个字符在文件中出现的频率。
2. 将每个字符及其频率作为一个节点,构建一个森林。
3. 从森林中选出两个频率最小的节点,将它们合并成一个新节点,并将合并后的节点重新插入到森林中。
4. 重复第3步,直到森林中只剩下一个节点,即为哈夫曼树的根节点。
下面是一个使用 C++ 实现构造哈夫曼树的示例代码:
```cpp
#include <iostream>
#include <queue>
#include <vector>
#include <fstream>
using namespace std;
// 定义哈夫曼树节点
struct Node {
char ch; // 字符
int freq; // 频率
Node *left, *right; // 左右子节点
Node(char ch, int freq) {
this->ch = ch;
this->freq = freq;
left = right = NULL;
}
};
// 比较器,用于优先队列排序
struct cmp {
bool operator()(Node *a, Node *b) {
return a->freq > b->freq;
}
};
// 构造哈夫曼树
Node* buildHuffmanTree(vector<int>& freq) {
priority_queue<Node*, vector<Node*>, cmp> pq;
for (int i = 0; i < 256; i++) {
if (freq[i] > 0) {
pq.push(new Node(i, freq[i]));
}
}
while (pq.size() > 1) {
Node *left = pq.top(); pq.pop();
Node *right = pq.top(); pq.pop();
Node *parent = new Node('$', left->freq + right->freq);
parent->left = left;
parent->right = right;
pq.push(parent);
}
return pq.top();
}
// 读取文件并统计字符频率
void readFile(string filename, vector<int>& freq) {
ifstream fin(filename);
char ch;
while (fin.get(ch)) {
freq[ch]++;
}
fin.close();
}
// 遍历哈夫曼树,生成编码表
void buildEncodingTable(Node* root, string code, vector<string>& encodingTable) {
if (root->left == NULL && root->right == NULL) {
encodingTable[root->ch] = code;
return;
}
buildEncodingTable(root->left, code + "0", encodingTable);
buildEncodingTable(root->right, code + "1", encodingTable);
}
int main() {
string filename = "test.txt";
vector<int> freq(256, 0);
readFile(filename, freq);
Node *root = buildHuffmanTree(freq);
vector<string> encodingTable(256);
buildEncodingTable(root, "", encodingTable);
// 输出编码表
for (int i = 0; i < 256; i++) {
if (freq[i] > 0) {
cout << (char)i << " " << encodingTable[i] << endl;
}
}
return 0;
}
```
这段代码会读取指定的文件,统计每个字符出现的频率,然后构造哈夫曼树,并生成每个字符的编码。最后输出编码表。你可以根据自己的需求进行修改和扩展。
阅读全文