22功能之败者树的解析与代码实现

22功能之败者树的解析与代码实现

1 败者树的构建过程
在这里插入图片描述

2 解析上图
败者树由内部节点与叶子节点组成。
1)内部节点指除了叶子节点与ls[0];
2)叶子节点就是数据节点;
若有K个数据,则叶子节点为K,内部节点为K-1。但是在代码实现过程中,需要有一个最小值与存放最小值下标的地方,而最小值放在叶子节点;最小值下标存放在ls[0]。故长度定义数据节点的数组为K+1;内部节点的长度为K。

Q1:上面为何数据节点要使用最小值INT_MIN?
因为方便在第一次调整的时候建立好败者树。

Q2:为何loserTree[2]下面的数据点有时是data[0],有时是data[n-1]?
因为叶子节点与内部节点建立关系是我们自己实现的,即
t=(s+Len)/2;这样我们调整败者树传进参数s时,就会规定你是data[0]还是data[n-1];总之一句话,因为叶子节点和内部节点的关系是我们自己定义的,数据怎么连接看连接的公式。不懂可以看下面的代码。

3 代码实现
int ls[K]; //ls[0]存最小值下标,1-K-1存内部节点,即每次的亚军
int b[k+1]; //ls[K]存最小值,0-K-1存数据

	void CreateLoser() {
		//1 初始化数据节点的最小值
		b[m_file] = MIN;
		//2 初始化内部节点记录的下标
		for (int i = 0; i < m_file; i++) {
			ls[i] = m_file;
		}
		//3 调整败者树
		for (int i = m_file - 1; i >= 0; i--) {
			Adjust(i);
		}
	}

	//调整败者树 s一开始代表当前节点,实际是一直指向胜利者,即数据最小的值(与用于初始化的最小值MIN不一样)
	void Adjust(int s) {
		int tmp;
		int t = (s + m_file) / (2);     //叶子节点与内部节点建立关系,t代表当前节点s的父节点
		while (t > 0) {                 //t=0,即父节点是ls[0]节点时,证明该次排序调整结束,已经找到最小值了嘛
			if (b[s] > b[ls[t]]) {      //新入树节点大于上一次的父节点,父节点记录新的失败者
				tmp = s;
				s = ls[t];           //s永远指向胜利者,即最小值
				ls[t] = tmp;              //父节点保存新的失败者
			}
			t = t / 2;                  //沿根节点上比较
		}
		ls[0] = s;
	}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值