二叉查找树

二叉查找树

二叉查找树,是一种基于堆性质的数据结构
给定一颗二叉树,树上的每个节点都会有一个值,然后对于每一个节点,都有如下性质:
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的左右是不平衡的(左右子树是相差很大的)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值