用 heapq 解哈夫曼编码问题——贪心算法

一、题目描述

【问题描述】使用贪心算法求解Huffman编码问题,具体来说就是,根据每个字符的出现频率,使用最小堆构造最小优先队列,构造出字符的最优二进制表示,即前缀码。在程序开始说明部分,简要描述使用贪心算法求解Huffman编码问题的算法过程。

【输入形式】在屏幕上输入字符个数和每个字符的频率。

【输出形式】每个字符的Huffman编码。

【样例输入】

 6

 45 13 12 16 9 5

【样例输出】

a 0

b 101

c 100

d 111

e 1101

f 1100

【样例说明】

 输入:字符个数为6,a至f每个字符的频率分别为:45, 13, 12, 16, 9, 5。

 输出:每个字符对应的Huffman编码。

 

二、代码实现

"""
哈夫曼编码
"""
import numpy as np
import heapq
import queue


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

    def __lt__(self, other):
        return self.freq < other.freq


class Heap:
    def __init__(self):
        self._queue = []

    def push(self, priority, item):
        heapq.heappush(self._queue, (priority, item))

    def pop(self):
        if self._queue:
            return heapq.heappop(self._queue)[-1]
        else:
            return None


def traceback(root, code):
    if root is None:
        return
    root.code = code

    traceback(root.left, code + "0")
    traceback(root.right, code + "1")


# 程序遍历
def print_res(root):
    q = queue.Queue()
    q.put(root)
    while not q.empty():
        node = q.get()
        if node.char:
            print(node.char, node.code)

        if node.left:
            q.put(node.left)
        if node.right:
            q.put(node.right)


def huffman(C):
    n = len(C)
    Q = Heap()

    for i in range(n):
        Q.push(C[i], Node(C[i], chr(97 + i)))

    for i in range(n-1):
        x = Q.pop()
        y = Q.pop()

        z = Node(x.freq + y.freq, None, x, y, None)
        Q.push(z.freq, z)

    return Q.pop()


def main():
    C = [45, 13, 12, 16, 9, 5]
    root = huffman(C)
    traceback(root, "")
    print_res(root)


if __name__ == '__main__':
    main()

 

你可能感兴趣的:(算法——贪心算法)