二叉搜索树实现

本文给出二叉搜索树介绍和实现

 

首先说它的性质:所有的节点都满足,左子树上所有的节点都比自己小,右边的都比自己大。

 

那这个结构有什么有用呢?

首先可以快速二分查找。还可以中序遍历得到升序序列,等等。。。

基本操作:

1、插入某个数值

2、查询是否包含某个数值

3、删除某个数值

 

根据实现不同,还可以实现其他很多种操作。

 

实现思路思路:

前两个操作很好想,就是不断比较,大了往左走,小了往右走。到空了插入,或者到空都没找到。

而删除稍微复杂一些,有下面这几种情况:

1、需要删除的节点没有左儿子,那就把右儿子提上去就好了。

2、需要删除的节点有左儿子,这个左儿子没有右儿子,那么就把左儿子提上去

3、以上都不满足,就把左儿子子孙中最大节点提上来。

 

当然,反过来也是成立的,比如右儿子子孙中最小的节点。

 

下面来叙述为什么可以这么做。

下图中A为待删除节点。

第一种情况:

 

1、去掉A,把c提上来,c也是小于x的没问题。

2、根据定义可知,x左边的所有点都小于它,把c提上来不影响规则。

 

第二种情况

 

3、B<A<C,所以B<C,根据刚才的叙述,B可以提上去,c可以放在b右边,不影响规则

4、同理

 

第三种情况

 

5、注意:是把黑色的提升上来,不是所谓的最右边的那个,因为当初向左拐了,他一定小。

因为黑色是最大,比B以及B所有的孩子都大,所以让B当左孩子没问题

而黑点小于A,也就小于c,所以可以让c当右孩子

大概证明就这样。。

下面我们用代码实现并通过注释理解

上次链表之类的用的c,循环来写的。这次就c++函数递归吧,不同方式练习。

定义

struct node
{
    int val;//数据
    node *lch,*rch;//左右孩子
};

插入

 node *insert(node *p,int x)
 {
     if(p==NULL)//直到空就创建节点
     {
         node *q=new node;
         q->val=x;
         q->lch=q->rch=NULL;
         return p;
     }
     if(x<p->val)p->lch=insert(p->lch,x);
     else p->lch=insert(p->rch,x);
     return p;//依次返回自己,让上一个函数执行。
 }

查找

 bool find(node *p,int x)
 {
     if(p==NULL)return false;
     else if(x==p->val)return true;
     else if(x<p->val)return find(p->lch,x);
     else return find(p->rch,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->lch=remove(p->rch,x);
      //以下为找到了之后
      else if(p->lch==NULL)//情况1
      {
          node *q=p->rch;
          delete p;
          return q;
      }
      else if(p->lch->rch)//情况2
      {
          node *q=p->lch;
          q->rch=p->rch;
          delete p;
          return q;
      }
      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;//调整黑点左孩子为B
          r->rch=p->rch;//调整黑点右孩子为c
          delete p;//删除
          return r;//返回给父
      }
      return p;
 }

 

  • 45
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 34
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔老大RabbitMQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值