嘉兴市网站建设_网站建设公司_全栈开发者_seo优化
2025/12/31 18:21:49 网站建设 项目流程

核心概念解析如下:

路径长度:指从一个结点到另一个结点之间所经过的边(分支)的数量。例如,从根结点到某一叶子结点的路径长度就是该路径上分支的总数。

树的路径长度:定义为从树根到每一个叶子结点的路径长度之和。它反映了整棵树的“平均深度”或结构紧凑性。

带权路径长度(WPL, Weighted Path Length):是哈夫曼树中的关键指标,计算公式为:
WPL=∑k=1nwk⋅lk \text{WPL} = \sum_{k=1}^{n} w_k \cdot l_kWPL=k=1nwklk
其中wkw_kwk是第kkk个叶子结点的权值,lkl_klk是该叶子到根结点的路径长度。WPL 越小,说明高频(大权值)节点越靠近根,整体效率越高。

哈夫曼树:给定nnn个具有确定权值的叶子结点,构造出的所有可能的二叉树中,WPL 最小的那个称为哈夫曼树(最优二叉树)。常用于数据压缩编码(如哈夫曼编码)。


示例说明分析(图 3-23)

假设四个叶子结点的权值分别为 2、4、5、7:

  • 图 (a):若所有叶子都在同一层(比如深度均为 2),则
    WPL=2×(2+4+5+7)=2×18=36 \text{WPL} = 2×(2+4+5+7) = 2×18 = 36WPL=2×(2+4+5+7)=2×18=36
    (注意原描述有误,“2×(2+4+5+7)”应解释为每个路径长度为2时加权求和)

  • 图 (b):构造出的哈夫曼树 WPL 更优:
    假设组合过程合理,得到结果:
    WPL=3×6+10+7=35(实际需根据具体结构验证) \text{WPL} = 3×6 + 10 + 7 = 35 \quad \text{(实际需根据具体结构验证)}WPL=3×6+10+7=35(实际需根据具体结构验证)
    此为最小 WPL,故图(b)为哈夫曼树。

  • 图 ©:结构更不平衡,导致较大权值节点更深,WPL 达到 43,性能最差。

结论:不同结构影响 WPL,哈夫曼算法旨在找出最优结构。


哈夫曼树构造算法步骤详解

  1. 初始化:将每个权值作为一个独立的单结点二叉树,形成森林FFF
  2. 选取与合并:在FFF中选出两棵根结点权值最小的树,合并成一棵新二叉树,新根的权值等于左右子树根权值之和。
  3. 更新集合:删除原来的两棵树,加入新树。
  4. 重复:直到FFF中只剩一棵树 —— 即为哈夫曼树。

示例:权值 [2, 4, 5, 7]
第一步:选 2 和 4 → 合并为 6
森林变为:[5, 6, 7]
第二步:选 5 和 6 → 合并为 11
森林变为:[7, 11]
第三步:7 和 11 → 合并为 18
得到最终哈夫曼树,总 WPL 可计算为最小值。


补充特征说明

  • 哈夫曼树不唯一:由于每次选择最小的两棵树时,左右子树可以互换位置,因此结构可能不同,但 WPL 值唯一。
  • 结点总数公式:对于nnn个叶子结点的哈夫曼树,总共会有m=2n−1m = 2n - 1m=2n1个结点(因为每合并一次减少一棵树,共需n−1n-1n1次合并,产生n−1n-1n1个内部结点)。
  • 存储方式:由于其静态特性,常用一维数组(如结构体数组)实现,记录父节点和子节点下标,适合非递归处理。
# Python 示例:哈夫曼树结点类classHuffmanNode:def__init__(self,weight,left=None,right=None):self.weight=weight self.left=left self.right=rightdefbuild_huffman_tree(weights):fromheapqimportheapify,heappop,heappush# 构建最小堆(Python heapq 是最小堆)nodes=[HuffmanNode(w)forwinweights]heapify(nodes,key=lambdax:x.weight)# 实际使用需自定义比较或包装whilelen(nodes)>1:a=heappop(nodes)b=heappop(nodes)merged=HuffmanNode(a.weight+b.weight,left=a,right=b)heappush(merged)returnheappop(nodes)# 返回根节点

注意:上述代码为示意,实际需对 heapq 进行适当封装以支持对象排序。
根据给定的权值序列手动构造哈夫曼树并计算其带权路径长度(WPL),可以按照以下系统步骤进行:


步骤一:列出所有叶子结点的权值

假设给定权值序列:[2, 4, 5, 7]

我们将每个权值视为一棵仅含根结点的二叉树。

初始森林 F = {2, 4, 5, 7}


步骤二:重复合并最小两棵树,直到只剩一棵树

第1轮:
  • 选两个最小的权值:2 和 4
  • 合并为新树,根权值 = 2 + 4 =6
  • 删除 2 和 4,加入 6
    → 森林变为:{5, 6, 7}
第2轮:
  • 选最小两个:5 和 6
  • 合并为新树,根权值 = 5 + 6 =11
  • 删除 5 和 6,加入 11
    → 森林变为:{7, 11}
第3轮:
  • 选最小两个:7 和 11
  • 合并为新树,根权值 = 7 + 11 =18
  • 删除 7 和 11,加入 18
    → 森林变为:{18},结束

最终得到的这棵根为 18 的二叉树就是哈夫曼树


步骤三:画出哈夫曼树结构(辅助理解)

18 / \ 7 11 / \ 5 6 / \ 2 4

注:左右子树可交换,不影响 WPL。


步骤四:计算 WPL(带权路径长度)

WPL = 所有叶子结点的权值 × 到根的路径长度之和

逐个看叶子:

叶子权值路径长度(从根到该叶的边数)贡献
717×1 = 7
525×2 = 10
232×3 = 6
434×3 = 12


WPL=7+10+6+12=35 \text{WPL} = 7 + 10 + 6 + 12 = \boxed{35}WPL=7+10+6+12=35

这是所有可能二叉树中 WPL 的最小值。


小结:手动构造哈夫曼树流程图解法

  1. 将权值从小到大排序;
  2. 每次取前两个最小的合并,生成父节点;
  3. 插入回列表并重新排序;
  4. 重复 n−1 次(n 是叶子数);
  5. 最后画出树形结构,计算各叶子深度 × 权值,求和得 WPL。

技巧提示

  • 不需要真正“画图”也能算 WPL:记录每个原始权值被合并了多少次 —— 实际上每合并一次,其所在子树的所有叶子路径长度都会增加 1。
  • 因此,也可以通过合并次数统计深度来间接计算。

例如:

  • 权值 2:参与了 3 次合并(第一次成6,第二次成11,第三次成18)→ 深度=3
  • 权值 4:同理 → 深度=3
  • 权值 5:参与两次后续合并 → 深度=2
  • 权值 7:只在最后一次合并 → 深度=1

结果一致。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询