数据结构——哈夫曼树

路径

路径与长度的概念

以一颗最简单的树作为例子:
在这里插入图片描述
在一棵树里面,从一个节点到另一个节点的路径,称之为这棵树的路径
例如B到H的路径为:
B->E->I
注意:一个节点到另一个节点的路径可以不止有一条

那么路径的长度就是一个节点到另一个节点之间所经历的树枝
例如:从B到I的路径长度为2,因为B->E->I中有两个“->”符号
注意:路径的长度并不是路径之间有几个节点就是多少,路径的长度指的是树枝的个数而不是节点的个数

带权路径长度

计算带权路径长度之前,我们必须给树的每一个节点赋予一个特殊的意义,一般我们会是数字,而这个数字就成为这个节点的,带权路径长度就是路径长度×权
还是用上面这颗树举例子:
在这里插入图片描述
正如每个节点上的蓝色的字体一样,蓝色的字体就是这个节点的权
例如求从A到I的带权路径长度:
A到I的路径长度为:3 I的权为9
则A到I的带权路径长度为3*9=27

树的带权路径和

依旧以上面的那棵树作为例子,还是一样的蓝色的字代表节点的权
树的带权路径和的概念是:树的叶子节点的带权路径和的和
先分析上面那棵树的叶子节点为:D、H、I、F、G
他们的路径长度分别为:2、3、3、2、2
他们的权分别为:4、8、9、6、7
则整棵树的带权路径和为:24 + 38 + 39 + 26 + 2*7 = 8 + 24 + 27 + 12 + 14 = 32 + 27 + 26 = 85

哈夫曼树

哈夫曼树的定义:

根据百度百科的定义:哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。

哈夫曼树的构建

哈夫曼树的构建通常是给定几个节点并且给定这几个节点所代表的特殊数值,要我们排出这颗哈夫曼树的结构
哈夫曼树构建的精髓在于每次选择权最小的两个节点构成一颗子树,并且将构成的子树的根重新按照从小到大的顺序放在原本的节点选项中,重复这个过程,最后得到的树就叫做哈夫曼树
我们以数字 2 3 6 7 10 19 21 32 作为例子

下面是第一步,先找到权值最小的两个节点2和3,构成一颗子树5-2-3,并且将这颗子树的根5 按照顺序放在原本的数列中
在这里插入图片描述
第二步骤,找到该数列中此时最小的两个节点5和6,组合成新的一颗子树,并且按照顺序放在数列中,把这颗子树的根作为数列中的一部分:
在这里插入图片描述
第三步:找到此时最小的两个权值7和10,并且组成一颗新的子树放在其中:
在这里插入图片描述
第四步:找到此时最小的两个权值11和17,构成一颗新的子树,并且将根节点放入其中
在这里插入图片描述
第五步:找到此时最小的两个权值19和21,组成一颗新的子树并且按照顺序放入其中
在这里插入图片描述
第六步:找到此时两个最小的28和32组成一颗子树并且按照顺序放入数列中
在这里插入图片描述
最后一步:将剩下的两颗子树组成为一颗子树,并且按照顺序排好
在这里插入图片描述

哈夫曼编码

哈夫曼编码遵从顺着哈夫曼树的路径,如果路径经过的节点是往左边走,则在树枝上面标记0,如果经过的路径是往右走,则在树枝的上面标记1
还是用一开始的哈夫曼树作为例子:
在这里插入图片描述
我们根据往左走为0,往右走为1的规则给这颗哈夫曼树的树枝上标记上标号:
在这里插入图片描述
接下来我们开始读取哈夫曼编码,哈夫曼编码的读取根据只需要读取从根节点开始,到需要读取的节点路径上经过的树枝的记号
下面举几个例子:
B的编码为:0
D的编码为:00
H的编码为:010
F的编码为:10
G的编码为:11

  • 18
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
(Huffman Tree)是一种特殊的二叉,用于数据压缩和编码。它的构建过程是根据字符出现的频率来确定每个字符的编码,使得出现频率高的字符具有较短的编码,而出现频率低的字符具有较长的编码。 以下是一个Python实现的哈的例子: ```python class TreeNode: def __init__(self, value, freq): self.value = value self.freq = freq self.left = None self.right = None def build_huffman_tree(char_freq): nodes = [TreeNode(char, freq) for char, freq in char_freq.items()] while len(nodes) > 1: nodes = sorted(nodes, key=lambda x: x.freq) left_node = nodes.pop(0) right_node = nodes.pop(0) parent_node = TreeNode(None, left_node.freq + right_node.freq) parent_node.left = left_node parent_node.right = right_node nodes.append(parent_node) return nodes[0] def encode_huffman_tree(root, code='', codes={}): if root is None: return if root.value is not None: codes[root.value] = code encode_huffman_tree(root.left, code + '0', codes) encode_huffman_tree(root.right, code + '1', codes) return codes def decode_huffman_tree(root, encoded_text): decoded_text = '' current_node = root for bit in encoded_text: if bit == '0': current_node = current_node.left else: current_node = current_node.right if current_node.value is not None: decoded_text += current_node.value current_node = root return decoded_text # 示例用法 char_freq = {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45} huffman_tree = build_huffman_tree(char_freq) huffman_codes = encode_huffman_tree(huffman_tree) encoded_text = ''.join([huffman_codes[char] for char in 'abcdef']) decoded_text = decode_huffman_tree(huffman_tree, encoded_text) print("Huffman Codes:", huffman_codes) print("Encoded Text:", encoded_text) print("Decoded Text:", decoded_text) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值