二叉查找树
二叉查找树,是一种基于堆性质的数据结构
给定一颗二叉树,树上的每个节点都会有一个值,然后对于每一个节点,都有如下性质:
1.这个节点不小于左儿子
2.这个节点不大于右儿子
那么上面性质就是一个二叉查找树(BST),然后要想进行排序,只需要走一下中序遍历
BST的建立
为了方便比较,我们一般在BST额外插入一个节点负无穷和一个节点正无穷,方便比较大小
struct BST
{
int l,r;
int date;
} a[size];
int tot,root,INF=99999999;
int add(int date)
{
a[++tot].date=date;
return tot;
}
void build()
{
add(-INF);add(INF);
root=1;
a[1].r=2;
}
BST的查找
在BST查找是否存在一个为date的点,设一个p等于root节点:
1.如果p为date,那么就已经找到了
2.如果p大于date
(1)如果p的左节点为空则不存在
(2)否则,递归p的左边子树
3.如果p小于date
(1)如果p的右节点为空则不存在
(2)否则,递归p的右边子树
int GET(int p,int date)
{
if(p==0) return ;//查找失败
if(date==a[p].date) return p;
return date<a[p].date? GET(a[p].l,date):GET(a[p].r,date);//两种情况
}
BST的插入
在BST中插入一个新的值date,其实和BST的查找功能差不多,只是我们在查找的时候如果找到空的就直接插入,比较简单粗暴,不断对根进行比较,如果小于往左走,大于往右走
void insert(int &p,int date)
{
if(p==0)
{
p=new(date);//空节点直接插入
return ;
}
if(date==a[p].date) return ;//已经存在不需要插入
if(date<a[p].date) insert(a[p].l,date);//递归左子树
if(date>a[p].date) insert(a[p].r,date);//递归右子树
}
BST的前驱后继
用后继为例子,date的后继就是在BST中大于date的前提中最小的一个
初始化ans为正无穷的编号,然后进行查找date,在查找过程中,每经过一个节点,都检查一个每个点的date,然后判断能不能更新ans
查找完成,有三种可能:
1.没有找到date,那么这个时候date的后继就在已经经过的点中,ans就是答案
2.找到了date,但是这个点p没有右子树,ans就是答案
3.找到了date,这个点有右子树,进行递归,一直往左走
总而言之,查找它自己的右边的第一个,即比他大的数,然后再往这个点往左走试试还能不能进行更新,直到不能更新,也就是大于date的前提中最小的一个,注意这个重点
int getnext(int date)
{
int ans=2;
int p=root;
while(p)
{
if(date==a[p].date)//查找成功
{
if(a[p].r>0)//存在右子树
{
p=a[p].r;
while(a[p].l) p=a[p].l;
ans=p;
}
break;
}
if(a[p].date>date&&a[p].date<a[ans].date) ans=p;//每次都尝试尝试能不能更新
p=date<a[p].date?a[p].l:a[p].r;
}
return ans;
}
BST的删除
在BST中删除一个date点
首先查找一个点p的值为date
如果p的子节点个数小于2,直接删除,并且让p的子节点代替p的位置,与p的父节点相连
如果p有左子树也有右子树,那么在BST中求出date的后继,然后删除,并且代替
void remove(int date)
{
int &p=root;
while(p)//查找date得到p
{
if(date==a[p].date) break;
p=date<a[p]date?a[p].l:a[p].r;
}
if(p==0) return ;
if(a[p].l==0)
{
p=a[p].r;//代替
}
if(a[p].r==0)
{
p=a[p].l;
}
if(a[p].l&&a[p].r)
{
int next=a[p].r;
while(a[next].l) next=a[next].l;
remove(a[next].date);
a[next].l=a[p].l,a[next].r=a[p].r;
p=next;
}
}
在随机数据中,BST的时间复杂度为O(log N)所以他还会被退化,那么BST的左右是不平衡的(左右子树是相差很大的)