ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

哈夫曼编码(Huffman Coding)

2022-03-31 20:03:02  阅读:209  来源: 互联网

标签:node 结点 哈夫曼 data self Coding None nodes Huffman


哈夫曼编码(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

 

标签:node,结点,哈夫曼,data,self,Coding,None,nodes,Huffman
来源: https://www.cnblogs.com/vicky2021/p/16069351.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有