[Python]哈夫曼编码

在这里插入图片描述

生成树


from heapq import heapify, heappush, heappop
from itertools import count

"""
https://www.cnblogs.com/xuchunlin/p/7247346.html
"""


def huffman(nodes, frequent):
    num = count()
    trees = list(zip(frequent, num, nodes))  # num ensures valid ordering
    heapify(trees)  # A min-heap based on freq
    while len(trees) > 1:  # Until all are combined
        value1, _, node1 = heappop(trees)  # Get the two smallest trees
        value2, _, node2 = heappop(trees)
        heappush(trees, (value1 + value2, next(num), [node1, node2]))  # Combine and re-add them
    # print trees
    return trees[0][-1]


if __name__ == '__main__':
    chars = "fecbda"
    weights = [5, 9, 12, 13, 16, 45]
    print(huffman(chars, weights))  # ['a', [['c', 'b'], [['f', 'e'], 'd']]]

编码


class Node:
    def __init__(self, freq):
        self.left = None
        self.right = None
        self.father = None
        self.freq = freq

    def isLeft(self):
        return self.father.left == self


# create Huffman-Tree创建Huffman树
def createHuffmanTree(nodes):
    queue = nodes[:]
    while len(queue) > 1:
        queue.sort(key=lambda item: item.freq)
        node_left = queue.pop(0)
        node_right = queue.pop(0)
        node_father = Node(node_left.freq + node_right.freq)
        node_father.left = node_left
        node_father.right = node_right
        node_left.father = node_father
        node_right.father = node_father
        queue.append(node_father)
    queue[0].father = None
    return queue[0]


# Huffman编码
def huffmanEncoding(nodes, root):
    codes = [''] * len(nodes)
    for i in range(len(nodes)):
        node_tmp = nodes[i]
        while node_tmp != root:
            if node_tmp.isLeft():
                codes[i] = '0' + codes[i]
            else:
                codes[i] = '1' + codes[i]
            node_tmp = node_tmp.father
    return codes


if __name__ == '__main__':
    chars = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
    freqs = [10, 4, 2, 5, 3, 4, 2, 6, 4, 4, 3, 7, 9, 6]
    chars_freqs = zip(chars, freqs)
    chars_freqs = sorted(chars_freqs, key=lambda item: item[1])
    nodes = [Node(item[1]) for item in chars_freqs]
    root = createHuffmanTree(nodes)
    encoding_map = huffmanEncoding(nodes, root)
    for item in zip(chars_freqs, encoding_map):
        print('Character:%s freq:%-2d   encoding: %s' % (item[0][0], item[0][1], item[1]))

复制

  1. 详细图解哈夫曼Huffman编码树
  2. 哈夫曼(huffman)树和哈夫曼编码
  3. Python 算法(2) 哈夫曼编码 Huffman Encoding
posted @ 2020-06-28 08:31  Sight-Tech  阅读(214)  评论(0编辑  收藏  举报