C/C++教程

哈夫曼编码(Huffman Coding)

本文主要是介绍哈夫曼编码(Huffman Coding),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

哈夫曼编码(Huffman Coding)是一种可变长的前缀码,可以有效地压缩数据:通常可以节省20%~90%的空间。哈夫曼设计了一个贪心算法来构造最优前缀码,被称为哈夫曼编码。

前缀码,没有任何码字是其他码字的前缀。 

思路

首先,获取字符与频率的关系。

其次,构建哈夫曼树。

最后,根据0=转向左孩子,1=转向右孩子,构建哈夫曼编码。

实现

# Python 3: Huffman code

class Node(object):
    def __init__(self, name: str = None, data=None):
        self.name: str = name
        self.data = data
        self.lchild: Node = None
        self.rchild: Node = None


class HuffmanTree(object):
    # 根据Huffman树的思想:以叶子节点为基础,建立Huffman树
    def __init__(self):
        self.nodes = []  # 根据输入的字符及其频数生成叶子节点
        self.root = None
        self.codes = {}

    def build(self, char_weights):
        """

        :param char_weights: e.g., char_weights = [('a', 7), ('b', 19), ('c', 2), ('d', 6), ('e', 32), ('f', 3), ('g', 21), ('h', 10)]
        """
        self.nodes = [Node(part[0], part[1]) for part in char_weights]
        while len(self.nodes) > 1:
            # 结点列表根据频率倒序排列。
            self.nodes.sort(key=lambda node: node.data, reverse=True)
            # 获取当前2个最小结点的值,并生成父结点。
            temp_node = Node(data=(self.nodes[-1].data + self.nodes[-2].data))
            # 将当前2个最小结点的值赋予父结点,最小结点是左结点,次最小结点是为右结点。
            temp_node.lchild = self.nodes.pop(-1)
            temp_node.rchild = self.nodes.pop(-1)
            # 将该父结点投入到结点列表中。
            self.nodes.append(temp_node)
        self.root = self.nodes[0]

    def traverse(self):
        self.__traverse(self.root)

    def __traverse(self, node):
        """
        in-order traverse
        :param node:
        """
        if node is None:
            return
        else:
            self.__traverse(node.lchild)
            print(node.data)
            self.__traverse(node.rchild)

    def generate_huffman_codes(self):
        self.__generate_huffman_codes(self.root, '0')

    def __generate_huffman_codes(self, node, code):
        if node is None:
            return
        else:
            if node.lchild is None and node.rchild is None and node.name is not None:
                self.codes[f'{node.name}({node.data})'] = code
            else:
                self.__generate_huffman_codes(node.lchild, code + '0')
                self.__generate_huffman_codes(node.rchild, code + '1')

#huffman codes:
#b(19)=000
#g(21)=001
#c(2)=010000
#f(3)=010001
#d(6)=01001
#a(7)=01010
#h(10)=01011
#e(32)=011

 

这篇关于哈夫曼编码(Huffman Coding)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!