已知下列字符A、B、C、D、E、F、G的权值分别是3、12、7、4、2、8、11。绘制以该权值为叶子结点的Huffman树,并求出树的带权路径长度值WPL和压缩率,并写出以上每个字符的编码。求数据结构代码
时间: 2023-10-09 18:07:52 浏览: 48
首先,根据Huffman树的构建方法,我们需要将所有叶子结点权值从小到大排序,然后每次选取权值最小的两个结点合并,直到所有结点都合并为一棵树。
按照上述步骤,我们可以得到如下Huffman树:
```
47
/ \
14 33
/ \ / \
5 9 11 22
/ \ \ / \
E F G C A
\
D
```
其中,WPL = 3\*2 + 12\*2 + 7\*2 + 4\*3 + 2\*4 + 8\*3 + 11\*3 = 103。
每个字符的编码可以根据Huffman树进行求解,规则为:从树根开始,向左走为0,向右走为1,直到叶子结点为止。例如,字符A的编码为10,字符F的编码为00,字符D的编码为1101。
压缩率的计算公式为:(1 - WPL / (字符总数 * 8)) * 100%。其中,字符总数为3+12+7+4+2+8+11=47,8为每个字符占用的位数。代入计算可得,压缩率约为30.43%。
以下是使用C++实现Huffman树的示例代码:
```cpp
#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <map>
using namespace std;
struct Node {
char ch;
int weight;
Node* left;
Node* right;
Node(char c, int w) : ch(c), weight(w), left(nullptr), right(nullptr) {}
};
struct Compare {
bool operator() (Node* a, Node* b) {
return a->weight > b->weight;
}
};
Node* buildHuffmanTree(map<char, int>& freq) {
priority_queue<Node*, vector<Node*>, Compare> pq;
for (auto it = freq.begin(); it != freq.end(); ++it) {
pq.push(new Node(it->first, it->second));
}
while (pq.size() > 1) {
Node* node1 = pq.top();
pq.pop();
Node* node2 = pq.top();
pq.pop();
Node* parent = new Node('#', node1->weight + node2->weight);
parent->left = node1;
parent->right = node2;
pq.push(parent);
}
return pq.top();
}
void getHuffmanCode(Node* root, string code, map<char, string>& codes) {
if (root == nullptr) return;
if (root->left == nullptr && root->right == nullptr) {
codes[root->ch] = code;
return;
}
getHuffmanCode(root->left, code + "0", codes);
getHuffmanCode(root->right, code + "1", codes);
}
int main() {
map<char, int> freq{{'A', 3}, {'B', 12}, {'C', 7}, {'D', 4}, {'E', 2}, {'F', 8}, {'G', 11}};
Node* root = buildHuffmanTree(freq);
map<char, string> codes;
getHuffmanCode(root, "", codes);
int wpl = 0;
for (auto it = codes.begin(); it != codes.end(); ++it) {
char ch = it->first;
int weight = freq[ch];
string code = it->second;
wpl += weight * code.length();
cout << "Character " << ch << " has code " << code << endl;
}
cout << "WPL = " << wpl << endl;
int totalBits = freq['A']*8 + freq['B']*8 + freq['C']*8 + freq['D']*8 + freq['E']*8 + freq['F']*8 + freq['G']*8;
double compressRatio = (1.0 - wpl / static_cast<double>(totalBits)) * 100.0;
cout << "Compression ratio = " << compressRatio << "%" << endl;
return 0;
}
```