TVA在纳米级表观缺陷检测中的范式跨越
2026/4/18 11:39:38
败者树是一种完全二叉树结构,用于高效选出多个归并段当前元素中的最小关键字对应段号。每次输出一个最小元素后,需从对应归并段读取下一个元素,并通过自底向上调整败者树,重新确定新的最小元素所在段。
voidAdjust(intls[],intb[],ints,intK){intt=(s+K)/2;// 计算当前归并段s在败者树中的父节点下标while(t>0){if(b[s]>b[ls[t]]){// 若当前段的关键字大于父节点对应段的关键字,则当前段为“败者”inttemp=s;s=ls[t];// 胜者继续向上比较(更新s为原父节点记录的胜者)ls[t]=temp;// 父节点记录本次比较的败者}t/=2;// 向上移动到父节点}ls[0]=s;// 最终s为全局胜者,即最小关键字所在的归并段号}ls[]数组的作用:长度为K的数组,ls[0]保存当前最小关键字对应的归并段号(即“冠军”),ls[1]到ls[K-1]保存各非叶节点记录的“败者”段号。ls数组大小通常为K(索引0~K-1)。叶子节点不显式存储,而是通过(s + K)/2定位其第一个父节点。b[s]沿路径与各级“胜者”比较,逐层淘汰败者,最终决定新的全局胜者存入ls[0]。ls[0]到ls[K-1],使得后续可以通过Adjust操作高效维护。由于败者树是一棵完全二叉树,有 K 个叶子节点(对应 K 路归并段),内部节点数为 K-1,因此ls[]数组大小为 K:
ls[0]:最终保存全局胜者(最小关键字对应的归并段号)ls[1] ~ ls[K-1]:保存各个非叶节点记录的“败者”段号voidLoserTreeInit(intls[],intb[],intK){// 初始化:将所有内部节点设为“无”或默认值(如-1)for(inti=0;i<K;i++){ls[i]=-1;}// 从最后一个叶子节点开始,倒序构造败者树for(ints=K-1;s>=0;s--){intt=(s+K)/2;// 父节点下标while(t>0){if(ls[t]==-1||b[s]>b[ls[t]]){// s 是败者,ls[t] 是胜者继续向上inttemp=s;s=ls[t];// 当前胜者继续上浮ls[t]=temp;// 记录败者}t/=2;}ls[0]=s;// 最终胜者放入 ls[0]}}Adjust的逻辑进行路径调整。ls[t] = -1表示该位置尚未有比较结果。ls[0]存储的是当前全局最小关键字所在的归并段号。假设四个归并段首元素为:
b[0]=15, b[1]=8, b[2]=3, b[3]=10
初始化完成后:
之后每次输出归并段2的元素后,读取下一个元素并调用Adjust(ls, b, 2, K)进行更新。
✅关键点总结: