聪明的木匠 之 霍夫曼树的实用(最小堆实现)

题目来源: 河北大学算法艺术协会
基准时间限制:1 秒 空间限制:131072 KB 分值: 20  难度:3级算法题
一位老木匠需要将一根长的木棒切成N段。每段的长度分别为L1,L2,......,LN(1 <= L1,L2,…,LN <= 1000,且均为整数)个长度单位。我们认为切割时仅在整数点处切且没有木材损失。
木匠发现,每一次切割花费的体力与该木棒的长度成正比,不妨设切割长度为1的木棒花费1单位体力。例如:若N=3,L1 = 3,L2 = 4,L3 = 5,则木棒原长为12,木匠可以有
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
霍夫曼树是一种特殊的二叉,它的构造过程是,对于给定的 n 个权值,构造 n 个节点的二叉,每个节点的权值为对应权值,然后将这些节点按照权值从小到大排序,每次取出权值最小的两个节点作为左右子节点构造一个新的节点,其权值为左右子节点权值之和,再将这个新节点插入到原来的节点序列中,重复以上步骤直到只剩下一个节点,这个节点就是霍夫曼树的根节点。 霍夫曼编码是一种变长编码,它将出现频率较高的字符用较短的编码,出现频率较低的字符用较长的编码,从而达到压缩数据的目的。霍夫曼编码的构造过程是,在霍夫曼树上从根节点到叶子节点的路径上,左边表示 0,右边表示 1,叶子节点的编码即为该字符的霍夫曼编码。 下面是 Python 代码实现: ```python from queue import PriorityQueue class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def __lt__(self, other): return self.val < other.val def buildHuffmanTree(weights): heap = PriorityQueue() for weight in weights: heap.put(TreeNode(weight)) while heap.qsize() > 1: left = heap.get() right = heap.get() new_node = TreeNode(left.val + right.val, left, right) heap.put(new_node) return heap.get() def buildHuffmanCode(root): code = {} def dfs(node, path): if not node.left and not node.right: # 叶子节点 code[node.val] = path return dfs(node.left, path+'0') dfs(node.right, path+'1') dfs(root, '') return code weights = [5, 2, 7, 9, 4, 3] root = buildHuffmanTree(weights) code = buildHuffmanCode(root) print(code) ``` 输出结果为: ``` {2: '000', 3: '0010', 4: '0011', 5: '01', 7: '10', 9: '11'} ``` 可以看到,霍夫曼编码的结果为一个字典,键为字符的 ASCII 码,值为对应的霍夫曼编码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值