值{5,29,7,8,14,23,3,11}构造哈夫曼树,画出此哈夫曼树,并为每 个叶子结点设计哈夫曼编码。
时间: 2023-08-17 19:06:04 浏览: 156
首先,我们需要根据权值大小构建哈夫曼树。具体步骤如下:
1. 对所有的权值进行从小到大的排序,得到 {3, 5, 7, 8, 11, 14, 23, 29}。
2. 选取权值最小的两个节点,将它们合并成一个新节点,权值为它们的和。将这个新节点作为一棵树的左右子树,其中左子树为权值较小的原始节点,右子树为权值较大的原始节点。
3. 将这个新节点插入到原始节点的位置,重新排序。
4. 重复步骤2和3,直到只剩下一个节点,这个节点就是哈夫曼树的根节点。
按照以上步骤,我们可以得到下面的哈夫曼树:
```
95
/ \
36 59
/ \ / \
14 22 23 36
/ \
8 14
```
接下来,我们为每个叶子节点设计哈夫曼编码。从根节点开始,如果往左走就在编码后加上0,如果往右走就在编码后加上1。最终,叶子节点的编码就是从根节点到该节点路径上的所有0和1。
根据哈夫曼树,我们可以得到每个叶子节点的编码:
```
5: 110
29: 00
7: 111
8: 101
14: 100
23: 01
3: 1100
11: 1101
```
因此,值{5,29,7,8,14,23,3,11}构造的哈夫曼树如上所示,并且每个叶子节点的哈夫曼编码分别为110、00、111、101、100、01、1100和1101。
相关问题
用c++完成哈夫曼树构造及其哈夫曼编码 输入格式: 请依次输入结点权值: 5 29 7 8 14 23 3 11 输出哈夫曼编码为: 5 :0001 29 :10 7 :1110 8 :1111 14 :110 23 :01 3 :0000 11 :001
在C++中,我们可以使用优先队列(如`std::priority_queue`)以及哈夫曼树的特性来构造哈夫曼树并生成哈夫曼编码。下面是一个简单的步骤概述:
1. 定义一个结构体或类`Node`,包含节点值(weight)和一个空的左子节点和右子节点。
```cpp
struct Node {
int weight;
Node* left = nullptr;
Node* right = nullptr;
};
```
2. 输入数据,创建一个大小为节点数的优先队列,并将所有节点插入其中,按照权重从小到大排序。
```cpp
int weights[] = {5, 29, 7, 8, 14, 23, 3, 11}; // 权重数组
std::priority_queue<std::pair<int, Node*>, std::vector<std::pair<int, Node*>>, std::greater<int>> pq(weights.begin(), weights.end());
```
3. 从队列中取出两个最小权重的节点,合并它们成为新节点(根节点),并将新节点的权重设为两个子节点的权重之和。同时将新节点放回队列。
```cpp
while (pq.size() > 1) {
auto node1 = pq.top(); pq.pop();
auto node2 = pq.top(); pq.pop();
pq.push({node1.first + node2.first, new Node{node1.first + node2.first, node1.second, node2.second}});
}
```
4. 最后的队列顶元素就是哈夫曼树的根节点。为了找到每个节点的哈夫曼编码,我们需要一个递归函数来遍历树并记录路径。
```cpp
void getHuffmanCode(Node* root, std::string code, std::map<int, std::string>& huffmanCodes) {
if (!root->left && !root->right) { // 叶子节点,直接添加哈夫曼编码
huffmanCodes[root->weight] = code;
} else {
getHuffmanCode(root->left, code + "0", huffmanCodes);
getHuffmanCode(root->right, code + "1", huffmanCodes);
}
}
```
5. 调用`getHuffmanCode`函数获取哈夫曼编码,然后输出结果。
```cpp
std::map<int, std::string> huffmanCodes;
getHuffmanCode(pq.top(), "", huffmanCodes);
// 输出哈夫曼编码
for (const auto& pair : huffmanCodes) {
std::cout << pair.first << ": " << pair.second << "\n";
}
```
2 3 5 7 8 11构造哈夫曼树
首先,将给定的数字按照从小到大的顺序排列,得到:2 3 5 7 8 11。
然后,选取两个权值最小的节点,将它们合并成一个新节点,新节点的权值为它们的权值之和。这里我们选取2和3,合并成一个节点,权值为5。
现在,我们的节点集合变为了{5, 5, 7, 8, 11},其中前两个5表示合并之后的节点。同样地,我们选取两个权值最小的节点,将它们合并成一个新节点,新节点的权值为它们的权值之和。这里我们选取5和7,合并成一个节点,权值为12。
现在,我们的节点集合变为了{8, 11, 12, 5},其中前三个节点表示合并之后的节点。再次选取两个权值最小的节点,将它们合并成一个新节点,新节点的权值为它们的权值之和。这里我们选取5和8,合并成一个节点,权值为13。
现在,我们的节点集合变为了{11, 12, 13},其中前两个节点表示合并之后的节点。最后,我们将剩下的两个节点合并成一个新节点,新节点的权值为它们的权值之和。这里我们选取11和12,合并成一个节点,权值为23。
现在,我们得到了一棵哈夫曼树,它的根节点的权值为23,左子树为11,右子树为12。左子树的左节点为2,右节点为3,右子树的左节点为5,右节点为7和8。
阅读全文