news 2026/4/15 23:17:47

败者树的作用是优化多路归并排序中寻找最小元素的过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
败者树的作用是优化多路归并排序中寻找最小元素的过程

败者树的作用是优化多路归并排序中寻找最小元素的过程。在 K 路归并中,传统方法需要每次比较 K 个归并段的当前记录以找出最小值,时间复杂度为 O(K),效率较低。而败者树通过构建一棵完全二叉树结构,将这一过程优化至 O(logK)。

  • 叶子节点:表示 K 个归并段当前待比较的记录,每个叶子对应一个归并段;
  • 内部节点:不存储胜者,而是记录“败者”——即在该轮比较中较大的记录所来自的归并段号;
  • 根节点的父节点 ls[0]:保存最终的“胜者”,即当前最小记录所属的归并段号。

算法流程详解(以 K=8 为例):

  1. 初始化阶段
    • 从每个归并段读取第一个记录存入数组b[1..K]
    • 构建初始败者树,所有内部节点初始化为“虚拟败者”K(防止越界),然后自底向上调整,确定最初的胜者和各层败者;
  2. Adjust(ls, i) 函数
    • 从第 i 个叶子节点(代表某个归并段的新记录)开始,沿路径向根部更新;
    • 每一层比较当前“参赛者”与原败者,胜者晋级参与上层比较,败者留在该节点;
    • 最终根节点的父节点ls[0]得到新的全局胜者;
  3. 归并主循环
    • 取出b[ls[0]]对应的记录输出到结果序列;
    • 调用Get_nextRec(ls[0])从该归并段读取下一条记录;
    • 若该段未空(非 MAXKEY),则将其作为新参赛者调用Adjust(ls, ls[0])更新败者树;
    • 若已空,则可用特殊标记处理或停止参与后续比较;
    • 重复直至所有归并段均为空;

关键优势分析:

  • 高效性:每次替换仅需 O(logK) 时间完成调整,显著优于朴素 O(K) 扫描;
  • 空间节省:败者树仅需 K−1 个内部节点(数组ls[0..K−1]),结构紧凑;
  • 可扩展性强:适用于大规模外部排序场景下的多路平衡归并;

边界控制机制:

  • 使用MINKEY表示无穷小,用于初始化;
  • 使用MAXKEY表示无穷大,当某归并段耗尽时返回此值,确保其不再参与有效竞争;

综上所述,败者树是一种专为多路归并设计的高效选择结构,核心在于“记录败者、传播胜者”的思想,极大提升了外部排序的整体性能。
Adjust(ls, i)是败者树的核心调整函数,其作用是从第i个叶子节点(即第i个归并段的新记录)开始,沿着从叶子到根的路径重新进行比赛,更新各层的“败者”,最终确定新的全局胜者,并将其存入ls[0]

✅ 假设前提:

  • 败者树是一棵完全二叉树,共有K个叶子节点(对应 K 路归并),K为 2 的幂;
  • 内部节点存储的是“败者”的归并段号(即较大的记录所在段号);
  • 根节点的父节点ls[0]存储当前胜者(最小记录所在的段号);
  • 叶子节点数据保存在数组b[1..K]中,b[i]表示第i段当前参与比较的记录关键字;
  • ls[1..K-1]存储败者树的内部节点(共 K−1 个);

📌 Adjust(ls, i) 实现逻辑(伪代码 + 解释)

voidAdjust(intls[],inti,intb[],intK){// s 表示当前正在上升的比赛节点(从叶子 i 开始)intt=0;// 当前层级对应的内部节点索引:t ∈ [K-1, K/2, ..., 1]intwinner=i;// 当前参赛的“胜者”段号(初始为 i)// 从叶子向上遍历每一层内部节点,直到根部for(intlevel=0;(1<<level)<K;level++){t=(K+winner)/2;// 父节点在 ls 中的索引(完全二叉树性质)if(ls[t]==K){// 初始化状态:该节点无有效败者,winner 直接晋级ls[t]=winner;winner=i;// 注意:这里应保持 winner 不变?需修正逻辑}else{// 比较当前 winner 与原 ls[t] 所代表的败者if(b[winner]<=b[ls[t]]){// winner 更小,继续晋级,原 ls[t] 成为新败者inttemp=ls[t];ls[t]=winner;winner=temp;}// 否则:原 ls[t] 更小,它继续晋级,winner 成为败者留在 ls[t]}// 继续下一轮比较,直到到达根节点上方}// 最终 winner 是全局最小者,存入 ls[0]ls[0]=winner;}

⚠️ 上述伪代码存在细节问题。更准确的做法如下:


✅ 正确实现方式(标准教科书版本):

voidAdjust(intls[],inti,intb[],intK){intt=(K+i)/2;// 当前比较层级的父节点索引while(t>0){// 比较当前参赛者 i 与 ls[t] 记录的旧败者if(b[i]>b[ls[t]]){// i 是败者,保留胜者 ls[t] 继续上行,i 下降到该层成为败者inttemp=i;i=ls[t];// 新参赛者是原来的胜者ls[t]=temp;// 当前败者记录下来}// 否则 i 是胜者,直接上行,败者仍为 ls[t]t/=2;// 移动到上一层父节点}// 最终 i 是胜者,记录在 ls[0]ls[0]=i;}

🔍 详细步骤说明(以 K=8,i=3 为例):

  1. 初始:b[3]更新了新记录,需重新调整。
  2. t = (8+3)/2 = 5→ 第一层父节点ls[5]
  3. 比较b[3]b[ls[5]]
    • b[3] > b[ls[5]],则3是败者,写入ls[5],原来ls[5]的值继续作为“胜者”参与上层;
    • 否则ls[5]仍是败者,3继续上行;
  4. t = 5/2 = 2ls[2],重复比较;
  5. t = 2/2 = 1ls[1],最后比较;
  6. t = 1/2 = 0结束,将最终胜者存入ls[0]

🎯 关键思想总结:

  • 只记录败者:每个内部节点保存的是在这次比赛中输掉的一方;
  • 胜者持续向上挑战:确保根部ls[0]总是当前最小元素来源;
  • 时间复杂度 O(logK):每轮向上走 log₂K 层,每层一次比较;
  • 空间效率高:仅用 K−1 个节点即可维护整个选择结构;

✅ 示例调用场景:

// 输出最小元素后,从第 i 段读取下一个记录b[i]=Get_nextRec(i);if(b[i]!=MAXKEY){Adjust(ls,i,b,K);// 重新调整败者树}else{// 归并段已空,可特殊处理(如不再参与)}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 17:28:29

物联网赋能新能源汽车:技术融合与产业变革

物联网技术正深度融入新能源汽车产业&#xff0c;成为推动其向智能化、网联化和绿色化转型的核心驱动力。截至2026年初&#xff0c;物联网与5G、AI、大数据等技术的协同创新&#xff0c;已在智能座舱、自动驾驶、远程监控及充电基础设施智能化等方面取得显著成果&#xff0c;形…

作者头像 李华
网站建设 2026/4/16 5:49:20

【Docker】核心概念 常用指令总结 Docker Compose

文章目录 核心概念指令一、守护进程&#xff08;Docker Daemon&#xff09;二、镜像&#xff08;Image&#xff09;三、容器&#xff08;Container&#xff09;四、卷管理五、容器挂载卷 数据卷多个容器挂载数据卷容器 Docker 容器和镜像的细节Docker镜像原理Dockerfile关键字D…

作者头像 李华
网站建设 2026/4/16 18:12:20

python数据结构之栈和队列

一、栈&#xff08;Stack&#xff09;栈是一种后进先出&#xff08;LIFO&#xff09;的线性数据结构。就像往手枪弹夹里装子弹时&#xff0c;子弹从弹夹口依次压入&#xff08;入栈 push&#xff09;&#xff0c;先装的子弹会沉到弹夹底部&#xff1b;开枪时&#xff0c;最上面…

作者头像 李华
网站建设 2026/4/16 12:23:15

springboot养殖畜牧业养牛可视化大屏设计与实现vue

目录摘要开发技术核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 SpringBoot与Vue结合的养殖畜牧业养牛可…

作者头像 李华
网站建设 2026/4/16 15:53:27

ssm springboot人脸识别物流运输管理系统vue

目录 摘要技术栈 开发技术 核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 摘要 基于SSM&#xff08;SpringSp…

作者头像 李华
网站建设 2026/4/16 12:28:34

通达信五行金针选股指标公式

VAR1:REF(CLOSE,1); VAR2:SMA(MAX(CLOSE-VAR1,0),7,1)/SMA(Abs(CLOSE-VAR1),7,1)*100; VAR8:SMA(MAX(CLOSE-VAR1,0),14,1)/SMA(ABS(CLOSE-VAR1),14,1)*100; VAR9:SMA(MAX(CLOSE-VAR1,0),21,1)/SMA(ABS(CLOSE-VAR1),21,1)*100; 五行金针:VAR2<15 AND VAR8<25 AND VAR9<…

作者头像 李华