联想拯救者BIOS高级设置终极指南:一键解锁隐藏选项的完整教程
2026/6/6 15:30:15
败者树的作用是优化多路归并排序中寻找最小元素的过程。在 K 路归并中,传统方法需要每次比较 K 个归并段的当前记录以找出最小值,时间复杂度为 O(K),效率较低。而败者树通过构建一棵完全二叉树结构,将这一过程优化至 O(logK)。
b[1..K];ls[0]得到新的全局胜者;b[ls[0]]对应的记录输出到结果序列;Get_nextRec(ls[0])从该归并段读取下一条记录;Adjust(ls, ls[0])更新败者树;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 个);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;}b[3]更新了新记录,需重新调整。t = (8+3)/2 = 5→ 第一层父节点ls[5]b[3]与b[ls[5]]:b[3] > b[ls[5]],则3是败者,写入ls[5],原来ls[5]的值继续作为“胜者”参与上层;ls[5]仍是败者,3继续上行;t = 5/2 = 2→ls[2],重复比较;t = 2/2 = 1→ls[1],最后比较;t = 1/2 = 0结束,将最终胜者存入ls[0];ls[0]总是当前最小元素来源;// 输出最小元素后,从第 i 段读取下一个记录b[i]=Get_nextRec(i);if(b[i]!=MAXKEY){Adjust(ls,i,b,K);// 重新调整败者树}else{// 归并段已空,可特殊处理(如不再参与)}