二叉搜索树
1、什么是二叉搜索树
二叉搜索树(Binary Search Tree)是一棵有序的二叉树,所以我们也可以称它为二叉排序树(不知道二叉树的童鞋,先看看二叉树:传送门)。具有以下性质的二叉树我们称之为二叉搜索树:若它的左子树不为空,那么左子树上的所有值均小于它的根节点;若它的右子树不为空,那么右子树上所有值均大于它的根节点。它的左子树和右子树分别也为二叉搜索树。
2、二叉搜索树的结构
二叉搜索树能够高效的进行一下操作:①插入一个数值②查询是否包含某个数值③删除某个数值
根据实现的不同,还可以实现其他各种操作,这是一种使用性很高的数据结构。我们来看一个例子:
这就是二叉搜索树的存储结构,所有的节点,都满足左子树上的比自己小,而右子树上的所有节点比自己大。二叉搜索树因为其有序性,所以它能够高效的管理数的集合
(1)查询
我们查找是否存在17:
<1>根节点是7,因为小于17,所以去右子树查找
<2>走到节点12,还是小于17,所以继续往右子树找
<3> 走到节点17,此时找到17。
(2)插入
我们使用查找的方式进行插入,以数字6为例,如图所示:
(3)删除
删除操作相对之前的其他两种操作,就略显复杂一些。一般来说我们可以分为三种情况:
<1>需要删除的节点没有左儿子,那么就把右儿子提上去
<2>需要删除的节点的左儿子没有右儿子,那么就把左儿子提上去
<3>不满足上述的两种情况的话,就把左子树中最大的节点放到要删除的节点上。
3、二叉搜索树的复杂度
无论我们执行哪一个操作,其所花的时间都和树的高度成正比。我们不难得知,二叉搜索树的平均复杂度为O(log n)。
4、二叉搜索树的实现
通过上述的了解,我们大致已经知道二叉搜索树的工作原理。所以现在我们就来简单的实现二叉搜索树基本的增删查的功能,代码如下:
- //表示节点的结构体
- struct node{
- int val;
- node *lch, *rch;
- };
- //插入整数x
- node *insert(node *p, int x){
- if(p == NULL){
- node *newNode = new node;
- newNode->val = x;
- newNode->lch = newNode->rch = NULL;
- p = newNode;
- }else{
- if(x < p->val) p->lch = insert(p->lch, x);
- else p->rch = insert(p->rch, x);
- }
- return p;
- }
- //查找整数x
- bool find(node *p, int x){
- if(p == NULL) return false;
- else if(p->val == x) return true;
- else if(p->val > x) return find(p->lch, x);
- else return find(p->rch, x);
- }
- //删除整数x
- node *remove(node *p, int x){
- if(p == NULL) return NULL;
- else if(x < p->val) p->lch = remove(p->lch, x);
- else if(x > p->val) p->rch = remove(p->rch, x);
- //情况<1>
- else if(p->lch == NULL){
- node *q = p->rch;
- delete p;
- return q;
- }
- //情况<2>
- else if(p->lch->rch == NULL){
- node *q = p->lch;
- q->rch = p->rch;
- delete p;
- return q;
- }
- //情况<3>
- else {
- node *q;
- for(q = p->lch; q->rch->rch != NULL; q = q->rch);
- node *r = q->rch;
- q->rch = r->lch;
- r->lch = p->lch;
- r->rch = p->rch;
- delete p;
- return r;
- }
- return p;
- }
//表示节点的结构体 struct node{ int val; node *lch, *rch; }; //插入整数x node *insert(node *p, int x){ if(p == NULL){ node *newNode = new node; newNode->val = x; newNode->lch = newNode->rch = NULL; p = newNode; }else{ if(x < p->val) p->lch = insert(p->lch, x); else p->rch = insert(p->rch, x); } return p; } //查找整数x bool find(node *p, int x){ if(p == NULL) return false; else if(p->val == x) return true; else if(p->val > x) return find(p->lch, x); else return find(p->rch, x); } //删除整数x node *remove(node *p, int x){ if(p == NULL) return NULL; else if(x < p->val) p->lch = remove(p->lch, x); else if(x > p->val) p->rch = remove(p->rch, x); //情况<1> else if(p->lch == NULL){ node *q = p->rch; delete p; return q; } //情况<2> else if(p->lch->rch == NULL){ node *q = p->lch; q->rch = p->rch; delete p; return q; } //情况<3> else { node *q; for(q = p->lch; q->rch->rch != NULL; q = q->rch); node *r = q->rch; q->rch = r->lch; r->lch = p->lch; r->rch = p->rch; delete p; return r; } return p; }