二叉搜索树

   二叉搜索树是一个可以动态管理集合的数据结构,相比于链表它可以更加有效地添加、搜索和删除数据。

  二叉搜索树的各个结点都会有它的键值,且规定任一个相对的左子树的键值小于它的根结点的键值,而右子树的键值大于根结点的键值。

  对于二叉搜索树,它的基本作用有插入、查找、删除。

 插入:

          插入过程的思想为:设当前的结点为x,要插入的结点为z,从根开始寻找插入的位置。若z的键值小于x,则将x的左儿子当作下一个x,反之,x的右儿子为下一个x,在此过程中,用y来存放访问的前一个结点,作为z的父结点候补。直到x为NULL,就找到了z的位置。而此时的y即为z的父结点。若y为NULL,说明插入前为空树,z为根结点。若插入前不为空,那么插入的结点z将根据键值大小成为y的左儿子或者右儿子。

#include <bits/stdc++.h>
using namespace std;
struct Node
{
    int key;
    Node *left,*right,*parent;
};

Node *root,*NIL;

void insert(int k)
{
    Node *x=root;
    Node *y=NIL;
    Node *z;

    z=(Node*)malloc(sizeof(Node));
    z->key=k;
    z->left=NIL;
    z->right=NIL;

    while(x!=NIL)
    {
        y=x;
        if(x->key<z->key) x=x->right;
        else x=x->left;
    }
    z->parent=y;
    if(y==NIL) root=z;
    else
    {
       if(z->key<y->key) y->left=z;
       else y->right=z;

    }
}

搜索:

  利用二叉搜索树的性质,从上至下搜索,如果小于当前结点键值则找当前结点的左儿子,如果大于则找当前结点的右儿子。

#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int key;
    Node *left,*right,*parent;
};

Node *root,*NUL;

Node * find(Node *u,int x)
{
    while(u!=NUL&&u->key!=x)
    {
        if(x<u->key) u=u->left;
        else u=u->right;
    }
    return u;
}

删除:

 删除操作会比插入和搜索复杂一些,对于要删除的结点z,要考虑三种情况:

      (1)z没有结点,删除z的父结点的子结点z,即它自己

    (2)z有一个结点x,将z的父结点的子结点改为x,也将x的父结点改为z的父结点,然后将z删去

     (3)z有两个结点,将z的后一个结点y(以中序排列为准)的键值复制到z,然后删除y

    在(3)中,寻找z的后一个结点,当z有右结点时,右子树中键值最小的结点就为z的后一个结点。不存在右结点时,就向上寻找第一个为左子结点的身份出现的父结点。如果二叉搜索树中不存在x的后一个结点则返回NULL。

#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int key;
    Node *left,*right,*parent;
};

Node *root,*NUL;

Node * getMinn(Node *u)
{
    while(u->left!=NUL)
    {
        u=u->left;
    }
    return u;
}

Node * find(Node *u,int x)
{
    while(u!=NUL&&u->key!=x)
    {
        if(x<u->key) u=u->left;
        else u=u->right;
    }
    return u;
}

Node * getSuccessor(Node *u)
{
    if(u->right!=NUL)
    {
        return getMinn(u->right);
    }
       Node *y=u->parent;
       while(y!=NUL&&u==y->right)
       {
           u=y;
           y=y->parent;
       }
      return y;
}

void treeDelete(Node *z)
{
    Node *y;
    Node *x;
    if(z->left==NUL||z->right==NUL)
    {
        y=z;
    }
    else y=getSuccessor(z);
    if(y->left!=NUL) x=y->left;
    else x=y->right;
    if(x!=NUL) x->parent=y->parent;
    if(y->parent==NUL) root=x;
    else
    {
       if(y->parent->left==y)
         y->parent->left=x;
       else y->parent->right=x;
    }
    if(y!=z) z->key=y->key;
    free(y);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值