C++ 二叉排序树(二叉查找树、二叉搜索树)

1.定义

二叉排序树(Binary Sort Tree)又称二叉查找树二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树:

  1. 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 左、右子树也分别为二叉排序树;

2.插入操作:

从根节点开始,若需要插入的值小于该节点则递归进入左子树,否则递归进入右子树,直到递归到空节点为止。
关键字序列:45 24 53 12 37 93
在这里插入图片描述

3.查询操作:

查询过程比较简单,首先将关键字和根节点的关键字比较,如果相等则返回节点的位置(指针);否则,如果小于根节点的关键字,则去左子树中继续查找;如果大于根节点的关键字,则去右子树中查找;如果找到叶子节点也没找到,则返回NULL。

如果二叉树的结构良好,其高度与树中结点个数n成对数关系,检索的时间开销为O(logn),但是如果树结构为链状的,检索的最坏时间可能达到O(n)。

4.删除操作:

1> 若需要删除的节点为叶子节点,那么可以直接删除。
2> 若需要删除的节点只有左子树(只有右子树),则直接将待删除节点的左子树(右子树)放在待删节点的位置,并释放待删节点的内存。

在这里插入图片描述
3> 如果需要删除的节点即有左子树又有右子树,此时就要在待删除节点的左子树中找到值最大的节点(左子树的最右边节点),将其放在待删除节点的位置。

在这里插入图片描述

在这里插入图片描述

5.代码实现:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef struct Tnode *p;
struct Tnode{
	p ls,rs;
	int data;
}; 
p root;
void insert(p &p,int val){
	if(p==NULL){
		p=new Tnode();
		p->data=val;
		p->ls=p->rs=NULL;
	}
	else if(val<p->data)	insert(p->ls,val);
	else	insert(p->rs,val);
}
p query(p p,int val){
	if(p==NULL)	return NULL;
	else if(val==p->data)	return p;
	else if(val<p->data)	return query(p->ls,val);
	else	return query(p->rs,val);
}
void del(p *root){
	p fa,s;
	if((*root)->ls==NULL){
		fa=(*root);
		(*root)=(*root)->rs;
		free(fa);
	}
	else if((*root)->rs==NULL){
		fa=(*root);
		(*root)=(*root)->ls;
		free(fa);
	}
	else{
		fa=(*root);
		s=(*root)->ls;
		while(s->rs!=NULL){
			fa=s;
			s=s->rs;
		}
		(*root)->data=s->data;
		if(fa!=(*root))	fa->rs=s->ls;
		else	fa->ls=s->ls;
		free(s);
	}
}
void delTnode(p *p,int val){
	if(!*p)	return;
	else{
		if((*p)->data==val)	del(p);
		else if((*p)->data>val)	delTnode(&(*p)->ls,val);
		else	delTnode(&(*p)->rs,val);
	}
}
void inorder(p p){
	if(p){
		inorder(p->ls);
		cout<<p->data<<" ";
		inorder(p->rs);
	}
	else	return;
}
int main(){
	root=NULL;
	insert(root,45);
	insert(root,24);
	insert(root,53);
	insert(root,12);
	insert(root,37);
	insert(root,93);
	inorder(root);
	delTnode(&root,12);
	puts("");
	inorder(root);
	puts("");
	printf("%d\n",query(root,24)->data);
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值