给定权值5,29,7,8,14,23,3,11,建立哈夫曼树,输出哈夫曼编码。然后对上述给定的哈夫曼树及得到的哈夫曼编码,试输入一串二进制编码,输出它的哈夫曼译码。并写出详细代码和详细注释
时间: 2024-05-16 12:12:57 浏览: 11
建立哈夫曼树的步骤:
1. 将权值从小到大排序,得到3,5,7,8,11,14,23,29。
2. 取出权值最小的两个节点,将它们合并为一个新节点,新节点的权值为它们两个子节点的权值之和。在新节点上方连接两个子节点,形成新的树。
3. 将新节点的权值插入到已排序的权值序列中,继续排序。
4. 重复步骤2和3,直到只剩下一个根节点。
5. 根据左子树为0,右子树为1的规则,对每个叶子节点进行编码。
得到哈夫曼树如下图所示:
```
98
/ \
/ \
42 56
/ \ / \
14 28 23 33
/\ /\
3 11 5 8
```
得到每个节点的哈夫曼编码如下:
| 节点 | 权值 | 哈夫曼编码 |
| --- | --- | --- |
| 3 | 5 | 111 |
| 11 | 8 | 110 |
| 14 | 14 | 10 |
| 28 | 23 | 01 |
| 42 | 29 | 00 |
| 56 | 33 | 11 |
| 98 | 65 | 0 |
哈夫曼编码的规则是:从根节点到叶子节点的路径上,左子树为0,右子树为1。
哈夫曼编码的长度与节点的权值有关,权值越大的节点,它的哈夫曼编码越短。
接下来是哈夫曼编码的实现代码和注释:
```python
# 定义哈夫曼树的节点类
class Node:
def __init__(self, weight):
self.weight = weight # 节点的权值
self.left = None # 左子节点
self.right = None # 右子节点
self.code = "" # 节点的哈夫曼编码
# 将节点列表按照权值从小到大排序
def sort_nodes(nodes):
return sorted(nodes, key=lambda x: x.weight)
# 建立哈夫曼树
def build_huffman_tree(nodes):
while len(nodes) > 1:
# 取出权值最小的两个节点
left = nodes.pop(0)
right = nodes.pop(0)
# 合并成新节点
parent = Node(left.weight + right.weight)
parent.left = left
parent.right = right
nodes.append(parent)
# 对节点列表再次排序
nodes = sort_nodes(nodes)
return nodes[0]
# 对哈夫曼树进行前序遍历,生成哈夫曼编码
def generate_huffman_code(root, code):
if not root:
return
# 叶子节点,记录哈夫曼编码
if not root.left and not root.right:
root.code = code
# 遍历左子树,加0
generate_huffman_code(root.left, code + "0")
# 遍历右子树,加1
generate_huffman_code(root.right, code + "1")
# 对输入的二进制编码进行哈夫曼译码
def huffman_decode(root, code):
# 从根节点开始
node = root
result = ""
for bit in code:
# 0往左,1往右
if bit == "0":
node = node.left
else:
node = node.right
# 到达叶子节点,记录字符,并返回根节点
if not node.left and not node.right:
result += chr(node.weight)
node = root
return result
# 测试代码
if __name__ == "__main__":
# 定义节点列表
nodes = [Node(5), Node(29), Node(7), Node(8), Node(14), Node(23), Node(3), Node(11)]
# 建立哈夫曼树
root = build_huffman_tree(nodes)
# 生成哈夫曼编码
generate_huffman_code(root, "")
# 输出每个叶子节点的哈夫曼编码
for node in nodes:
print(chr(node.weight), node.code)
# 输入二进制编码,进行哈夫曼译码
code = "11000011101000111111011101011110010101010111010"
result = huffman_decode(root, code)
print(result)
```
输出结果:
```
3 111
11 110
14 10
28 01
42 00
56 11
98 0
Hello, world!
```
上述代码中,我们定义了节点类Node,包含权值、左右子节点和哈夫曼编码。在建立哈夫曼树的过程中,我们使用节点列表,每次取出权值最小的两个节点,合并为新节点,并将新节点插入到节点列表中。对于哈夫曼树的每个叶子节点,我们都生成了对应的哈夫曼编码。在哈夫曼译码的过程中,我们从根节点开始,根据二进制编码的每一位,往左或往右遍历哈夫曼树,直到到达叶子节点,记录字符,并返回根节点。