FHQ-Treap 分裂递归瓶颈,关于递归回溯
查看原帖
FHQ-Treap 分裂递归瓶颈,关于递归回溯
1325916
VelvetChords楼主2025/7/26 23:05

想写详解,然后自己遇到瓶颈了(捂脸

大概是这样:

分裂模板:

/*
split 函数:按值分裂树
now:当前处理的节点下标
val:分裂的关键值
x:输出参数,存储所有值<=val的子树根
y:输出参数,存储所有值>val的子树根

递归地将树分裂为两部分:
x:所有值<=val的子树的根节点
y:所有值>val的子树的根节点
*/
void split(int now,int val,int &x,int &y)//直接修改外面的全局变量 x 和 y 
{
	if(!now) 
	{
		x=y=0;
		return;
	}
	if(tree[now].val<=val)//当前节点值<=val,应放入x树
	{
		
		x=now;// 当前节点作为x树的根
		split(tree[now].r,val,tree[now].r, y);//递归处理右子树,分裂点仍然是val
	} 
	else//当前节点值>val,应放入y树
	{
		
		y=now;//当前节点作为y树的根
		split(tree[now].l,val,x,tree[now].l);//递归处理左子树,分裂点仍然是val
	}
}

问题是这样的:

我现在有一棵树(圈内为权值,圈外为编号):

pVJLxiR.png

我们假设给定的 k=3k=3,为了让大家更直观体验递归过程,我挑战手算递归!

递归次数nowvalxy递归操作
第一次处理1601split(tree[1].l=2,3,x=0,tree[1].l=2)
第二次处理2222split(tree[2].r=4,3,tree[2].r=4, y=2)
第三次处理5445=tree[1].lsplit(tree[5].l=0,3,x=2,y=tree[5].l=0)
第四次处理0,return后回溯00return
第一次回溯(回到split(tree[2].r=4,3,tree[2].r=5, y)5405return
第二次回溯(回到split(tree[1].l=2,3,x=0,tree[1].l)222tree[2].y=y=4return
第三次回溯(回到split(root=3,3,x,y)16tree[1].l=x=26结束

但是回溯这边我自己都没看懂,需要更详细的说明,哪位大佬可以帮助我(就当我递归底子没打好)?

2025/7/26 23:05
加载中...