splay-前驱后继

在平衡树中,经常会让我们查一下一个值的前驱和后继是谁,写两个函数就非常麻烦好吧,所以这里咱们用一点小技巧来让他变

成一个函数(这里的前驱后继定义时包括与本身相等的值)

代码

点击查看代码
int nxt(int k)
	{
		if(!m[rt].size) return 0;
		int root=rt;
		while(k!=m[root].val&&m[root].ch[k>m[root].val])root=m[root].ch[k>m[root].val];
		splay(root);
		return root?m[root].val:m[rt].val;
	}

原理解析

这个代码本质是在查后继,但如果我们想再查前驱怎么办,只要再调用一次就好了,就像下面的操作一样

image

这里的 \(temp\) 是后继,\(mp\) 是前驱。

这实际上全是代码中 \(splay\) 的功劳,我们先将第一个大于等于 \(k\) 的值转到根,那么下一次第一次跳时肯定会往左子树

去跳,而左子树没有比 \(k\) 大的,所以只需要在其中找最大的那个值就是第一个小于等于 \(k\) 的值

posted @ 2024-07-05 09:57  _君の名は  阅读(31)  评论(0)    收藏  举报