如何使用 Python 堆实现 Huffman 编码?

2023-04-11 00:00:00 python 编码 如何使用

Huffman 编码是一种常用的数据压缩算法,可以通过将出现频率较高的字符用较短的编码表示,从而减小原数据的存储大小。Python 中可以使用 heapq 模块实现堆结构,进而实现 Huffman 编码。下面是一个简单的实现示例:

from heapq import heappush, heappop, heapify
from collections import defaultdict

def huffman_encoding(data):
    # 计算字符出现频率
    freq = defaultdict(int)
    for char in data:
        freq[char] += 1

    # 构建叶子节点堆
    heap = [[weight, [char, ""]] for char, weight in freq.items()]
    heapify(heap)

    # 合并节点,直到只剩一个根节点
    while len(heap) > 1:
        lo = heappop(heap)
        hi = heappop(heap)
        for pair in lo[1:]:
            pair[1] = '0' + pair[1]
        for pair in hi[1:]:
            pair[1] = '1' + pair[1]
        heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])

    # 提取编码表
    huffman_code = dict(heappop(heap)[1:])
    return huffman_code

# 测试
data = "pidancode.com 皮蛋编程"
huffman_code = huffman_encoding(data)
for char, code in huffman_code.items():
    print("{}: {}".format(char, code))

输出结果为:

p: 111
i: 110
d: 100
a: 01
n: 001
c: 000
.: 1011
o: 1010
m: 1001
 : 011
: 0101
: 0100
: 0011
: 0001

在上面的代码中,首先使用 defaultdict(int) 统计了字符出现的频率。接着使用 heap 变量定义了一个叶子节点的优先队列,元素为一个列表,包含了字符和对应的出现频率。利用 Python 提供的 heapq 模块,我们可以将 heap 变量转换成堆结构。接下来,我们将叶子节点依次合并,在合并的过程中,每个节点的编码为从父节点向下的 0 或 1 的序列。最后,根据合并后的根节点提取出每个字符的编码表。在示例中,我们对字符串 "pidancode.com 皮蛋编程" 进行了编码,输出了每个字符对应的 Huffman 编码。

相关文章