步骤:
统计输入数据中每个符号的出现频率。
根据频率构建哈夫曼树。首先创建一个包含所有符号的叶子节点集合,每个节点的权重为符号的频率。然后重复以下步骤直到只剩下一个根节点:
从节点集合中选择两个权重最小的节点,作为左右子节点创建一个新的父节点。
将新节点的权重设为左右子节点权重之和。
将新节点加入节点集合。
从节点集合中删除原先选出的两个节点。
根据哈夫曼树为每个符号分配唯一的编码。从根节点出发,沿着左子树走为0,沿着右子树走为1,记录下路径上的0和1即为符号的编码。
使用生成的编码对输入数据进行压缩。将每个符号替换为对应的编码。
将压缩后的数据以及编码表(记录每个符号的编码)一起保存,以便解压缩时使用。
from heapq import heapify, heappush, heappop
from collections import defaultdict
def build_huffman_tree(freq_dict):
"""构建哈夫曼树"""
heap = [[freq, [char, ""]] for char, freq in freq_dict.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:])
return sorted(heappop(heap)[1:], key=lambda x: (len(x[-1]), x))
def encode(data):
"""对数据进行哈夫曼编码"""
freq_dict = defaultdict(int)
for char in data:
freq_dict[char] += 1
huffman_tree = build_huffman_tree(freq_dict)
encoding_dict = dict(huffman_tree)
encoded_data = ""
for char in data:
encoded_data += encoding_dict[char]
return encoded_data, encoding_dict
def decode(encoded_data, encoding_dict):
"""对哈夫曼编码进行解码"""
decoding_dict = {v: k for k, v in encoding_dict.items()}
decoded_data = ""
code = ""
for bit in encoded_data:
code += bit
if code in decoding_dict:
decoded_data += decoding_dict[code]
code = ""
return decoded_data
data = "mississippi river"
encoded_data, encoding_dict = encode(data)
decoded_data = decode(encoded_data, encoding_dict)
print("原始数据:", data)
print("编码后的数据:", encoded_data)
print("解码后的数据:", decoded_data)
原始数据: mississippi river
编码后的数据: 11101110100000111011110110011101100000010111110101
解码后的数据: mississippi river