掌握哈夫曼树、哈夫曼编码的概念和基本理论,设计实现哈夫曼编码
时间: 2023-07-03 20:08:35 浏览: 74
哈夫曼树是一种小根堆,它的每个节点都有一个权值,哈夫曼树的根节点距离其它叶子节点最远,因此可以用于构建最优二进制编码。
构建哈夫曼编码的过程如下:
1. 统计字符的出现频率,并按照从小到大的顺序构建哈夫曼树。
2. 对于哈夫曼树中的每个叶子节点,将其对应的字符编码为0,向上遍历到根节点,左儿子对应的编码为0,右儿子对应的编码为1。
3. 遍历待编码的字符串,根据哈夫曼树的编码规则将每个字符编码成二进制数。
4. 将所有编码后的二进制数拼接起来即为哈夫曼编码。
下面是Python实现哈夫曼编码的示例代码:
```python
import heapq
from collections import defaultdict
def huffman_encoding(data):
freq = defaultdict(int)
for c in data:
freq[c] += 1
heap = [[wt, [sym, '']] for sym, wt in freq.items()]
heapq.heapify(heap)
while len(heap) > 1:
lo = heapq.heappop(heap)
hi = heapq.heappop(heap)
for pair in lo[1:]:
pair[1] = '0' + pair[1]
for pair in hi[1:]:
pair[1] = '1' + pair[1]
heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])
huff_code = dict(heapq.heappop(heap)[1:])
encoded_data = ''.join([huff_code[c] for c in data])
return encoded_data, huff_code
def huffman_decoding(encoded_data, huff_code):
inv_huff_code = {v: k for k, v in huff_code.items()}
decoded_data = ''
i = 0
while i < len(encoded_data):
j = i + 1
while encoded_data[i:j] not in inv_huff_code:
j += 1
decoded_data += inv_huff_code[encoded_data[i:j]]
i = j
return decoded_data
if __name__ == '__main__':
data = 'hello world'
encoded_data, huff_code = huffman_encoding(data)
decoded_data = huffman_decoding(encoded_data, huff_code)
print(encoded_data) # 100011011001110110101001011010000
print(decoded_data) # hello world
```
在上面的代码中,我们首先使用`defaultdict`统计字符出现频率,并将其存储在堆中。然后我们使用循环从堆中弹出两个最小的元素,合并它们并将它们放回堆中的过程,直到堆中只有一个元素。在这个过程中,我们将左儿子赋值为0,右儿子赋值为1,并将哈夫曼编码存储在一个字典中。最后,我们将编码后的二进制数拼接起来并返回哈夫曼编码。
对于解码过程,我们只需要将哈夫曼编码反转并存储在另一个字典中,然后遍历编码后的二进制数并查找对应的字符即可。
阅读全文