upd:把它叫成宗法树被lxl骂了,现在改一下
ps:由于CSDN没有替换功能,而且博主很懒,所以下面名字不改,大家清楚就好(逃
一看题目是不是很懵逼?
那就对了!
这个数据结构本来是没有名字的,由一个毒瘤dalao发明并传给讲师,讲师再交给我们。
至于这个名字,则是学员中一位毒瘤想到的。原因待会儿再讲。
为了方便,以下就称这种数据结构为“宗法树”。
宗法树是一种类似于平衡树的数据结构,但似乎更简单。它支持以下6种功能:
1、插入x
2、删除x(若有多个x,只删除一个)
3、求x的排名(严格比x小的数的个数+1)
4、求第x个数(同上)
5、求x的前驱(最大的小于x的数)
6、求x的后继(最小的大于x的数)
以上6种功能均为平衡树基本功能,但用代码量更小的宗法树也可以实现。
宗法树的性质:
1、是一棵二叉树
2、它的数字都存在叶子节点里
3、非叶子节点存储子树的最大值/最小值
4、每个非叶子节点的左子树里的数全都小于右子树里的数。
5、每个非叶子节点都必须有两棵子树
比如这样一棵宗法树:
而下面,我将按顺序讲解每一种功能的实现。
1、插入
以上面那棵宗法树为例,如果我们想插入6:
1、从根节点出发,发现左儿子的值是5<6,于是向右儿子递归
2、发现5号节点是叶子节点,于是在5号节点下方再建两个新节点6、7
3、5号节点原来的值9>6,所以将9放到右儿子,6放到左儿子
4、回溯更新
插入结果:
代码实现:
void insert(int &k,int x)
{
if (!k)//没有这个点,即第一次插入
{
new_tr(k,x);//动态开点
return;
}
if (leaf(k))//叶子节点
{
new_tr(tr[k].lson,min(x,tr[k].v));//建左儿子