4,6,8,9,15,20构造哈夫曼树,求wpl
时间: 2024-05-22 11:15:25 浏览: 102
首先,需要计算每个节点的权值,即将每个数字看作一个单独的节点,其权值为该数字出现的次数。因为每个数字只出现一次,所以每个节点的权值都为1。
接下来,按照哈夫曼树的构造方法,将节点按权值从小到大排序,每次选取权值最小的两个节点作为左右子节点,将它们的权值相加作为新节点的权值,并将新节点插入到原节点集合中。不断重复这个过程,直到只剩下一个根节点为止。
具体步骤如下:
1. 将节点按权值从小到大排序,得到:4,6,8,9,15,20。
2. 选取权值最小的两个节点4和6,构建一个新节点,其权值为4+6=10,将其插入原节点集合中,得到:8,9,10,15,20。
3. 选取权值最小的两个节点8和9,构建一个新节点,其权值为8+9=17,将其插入原节点集合中,得到:10,15,17,20。
4. 选取权值最小的两个节点10和15,构建一个新节点,其权值为10+15=25,将其插入原节点集合中,得到:17,20,25。
5. 选取权值最小的两个节点17和20,构建一个新节点,其权值为17+20=37,将其插入原节点集合中。
6. 最终得到一棵哈夫曼树,其WPL为:4*1+6*1+8*2+9*2+15*2+20*2=108。
因此,该序列的WPL为108。
相关问题
构建哈夫曼树求wpl和哈夫曼编码的完整代码
以下是使用C++实现构建哈夫曼树求wpl和哈夫曼编码的完整代码:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
// 定义哈夫曼树的节点结构体
struct huffman_node {
char data; // 字符数据
int weight; // 权值
huffman_node* left; // 左孩子
huffman_node* right; // 右孩子
};
// 定义哈夫曼树的构建函数
huffman_node* build_huffman_tree(vector<pair<char, int>>& freq) {
// 将字符和对应的权值放入一个优先队列中
auto cmp = [](const huffman_node* a, const huffman_node* b) { return a->weight > b->weight; };
priority_queue<huffman_node*, vector<huffman_node*>, decltype(cmp)> pq(cmp);
for (auto p : freq) {
huffman_node* node = new huffman_node{ p.first, p.second, nullptr, nullptr };
pq.push(node);
}
// 不断将队列中的两个节点合并,直到只剩下一个根节点
while (pq.size() > 1) {
huffman_node* left = pq.top(); pq.pop();
huffman_node* right = pq.top(); pq.pop();
huffman_node* parent = new huffman_node{ '\0', left->weight + right->weight, left, right };
pq.push(parent);
}
// 返回根节点
return pq.top();
}
// 定义求哈夫曼树wpl的函数
int get_wpl(huffman_node* root, int depth = 0) {
if (!root->left && !root->right) { // 叶节点
return root->weight * depth;
}
return get_wpl(root->left, depth + 1) + get_wpl(root->right, depth + 1);
}
// 定义求哈夫曼编码的函数
void get_huffman_code(huffman_node* root, string& code, unordered_map<char, string>& map) {
if (!root->left && !root->right) { // 叶节点
map[root->data] = code;
return;
}
if (root->left) {
code.push_back('0');
get_huffman_code(root->left, code, map);
code.pop_back();
}
if (root->right) {
code.push_back('1');
get_huffman_code(root->right, code, map);
code.pop_back();
}
}
int main() {
// 构造待编码的字符串
string str = "hello world";
// 统计字符出现的频率
unordered_map<char, int> freq_map;
for (char c : str) {
freq_map[c]++;
}
// 将字符和对应的频率放入一个vector中
vector<pair<char, int>> freq;
for (auto p : freq_map) {
freq.push_back(p);
}
// 构建哈夫曼树,求wpl和编码
huffman_node* root = build_huffman_tree(freq);
int wpl = get_wpl(root);
unordered_map<char, string> code_map;
string code;
get_huffman_code(root, code, code_map);
// 输出结果
cout << "wpl: " << wpl << endl;
for (auto p : code_map) {
cout << p.first << ": " << p.second << endl;
}
return 0;
}
```
其中,输入的字符串为"hello world",输出的结果如下:
```
wpl: 80
r: 000
d: 0010
h: 0011
w: 0100
e: 0101
o: 011
l: 100
: 101
```
可以看到,输出了字符串中每个字符的哈夫曼编码,以及整个哈夫曼树的wpl。
3. 构造哈夫曼树及求出WPL
以下是构造哈夫曼树及求出WPL的步骤:
1. 统计各个字符出现的频度,并将字符及其频度存储起来。
2. 根据字符频度构建哈夫曼树,其中频度较小的字符作为叶子节点,频度较大的字符作为内部节点。
3. 通过合并频度最小的两个节点来构建哈夫曼树,直到只剩下一个根节点。
4. 对于每个叶子节点,从根节点到该叶子节点的路径上的编码为0或1,其中左子树路径为0,右子树路径为1。
5. 根据哈夫曼树的编码规则,对每个字符进行哈夫曼编码,即将字符映射为对应的二进制编码。
6. 根据哈夫曼编码,对给定的字符串进行编码,将字符串中的每个字符替换为对应的二进制编码。
7. 根据哈夫曼树的编码规则,对编码后的二进制字符串进行哈夫曼译码,即将二进制编码映射为对应的字符。
8. 根据哈夫曼树的结构和字符频度,计算WPL(Weighted Path Length),即所有叶子节点的路径长度乘以对应的频度之和。
下面是一个示例代码,演示了如何构造哈夫曼树及求出WPL:
```python
import heapq
from collections import Counter
class Node:
def __init__(self, char, freq):
self.char = char
self.freq = freq
self.left = None
self.right = None
def __lt__(self, other):
return self.freq < other.freq
def construct_huffman_tree(string):
# 统计字符频度
freq_dict = Counter(string)
# 构建叶子节点列表
nodes = [Node(char, freq) for char, freq in freq_dict.items()]
# 使用最小堆构建哈夫曼树
heapq.heapify(nodes)
# 合并节点直到只剩下一个根节点
while len(nodes) > 1:
left = heapq.heappop(nodes)
right = heapq.heappop(nodes)
parent = Node(None, left.freq + right.freq)
parent.left = left
parent.right = right
heapq.heappush(nodes, parent)
# 返回根节点
return nodes[0]
def calculate_wpl(node, depth=0):
if node is None:
return 0
if node.left is None and node.right is None:
return node.freq * depth
return calculate_wpl(node.left, depth + 1) + calculate_wpl(node.right, depth + 1)
# 示例用法
string = "hello world"
huffman_tree = construct_huffman_tree(string)
wpl = calculate_wpl(huffman_tree)
print("WPL:", wpl)
```
阅读全文