• 二叉排序树(二叉搜索树)


    知识点总结报告

    知识点:

    二叉排序树

    (原理)二叉排序树又称二叉搜索树。其定义为二叉排序树或者空树或者满足以下性质的二叉树。

    性质1

    若根节点的左子树非空,则左子树上的所有结点关键字均小于根结点关键字

    性质2

    若根节点的右子树非空,则右子树上的所有结点关键字均大于根结点关键字

    性质3

    根结点的左、右子树本身又各是一棵二叉排序树

     二叉排序树结点类型

    typede fstruct node      //元素类型

    {  KeyType key;      //关键字项

      Info Type data;      //其他数据域

      struct node *lchild,*rchild;  //左、右孩子指针

    }BSTNode;

    二叉排序树的插入和创建

      插入的递归算法InsertBST( )

    bool InsertBST(BSTNode *&bt,KeyType k)  //在二叉排序树bt中插入一个关键字为k的结点,若插入成功返回真,否则返回假

    {  if (bt==NULL)             //原树为空,新插入的结点为根结点

      {  bt=(BSTNode *)malloc(sizeof(BSTNode));

        bt->key=k;bt->lchild=bt->rchild=NULL;

        return true;

      }

      else if(k==bt->key)          //树中存在相同关键字的结点,返回假

        return false;

      else if(k<bt->key)

        return InsertBST(bt->lchild,k);     //插入到左子树中 

      else     

        return InsertBST(bt->rchild,k);      //插入到右子树中

    }

      创建二叉排序树CreateBST( )

    BSTNode *CreateBST(KeyType A[ ],int n)      //创建二叉排序树  返回BST树根结点指针

    {  BSTNode *bt=NULL;              //初始时bt为空树

      int i=0;

      while(i<n)

      {  InsertBST(bt,a[i]);              //将关键字a[i]插入二叉排序树bt中

        i++;

      }

      return bt;                    //返回建立的二叉排序树的根指针

    }

      二叉排序树的查找(在二叉排序树bt上查找关键字为k的元素,成功时返回该结点指针,否则返回NULL)

    BSTNode *SearchBST(BSTNode *bt,KeyType k)      //二叉排序树查找

    {  if(bt==NULL||bt->key==k)               //递归结束条件

        return bt;                    

      if(k<bt->key)

        return SearchBST(bt->lchild,k);           //在左子树中递归查找

      else

        return SearchBST(bt->rchild,k);            //在右子树中递归查找

    }

      如果不仅要找到关键字为k的结点,还要找到双亲结点,采用递归算法如下:

    BSTNode *SearchBST1(BSTNode *bt,KeyType k,BSTNode *f1,BSTNode *&f)/*在二叉排序树bt上查找关键字为k的结点,若查找成功,该函数返回该结点指针,f返回其双亲结点,否则,该函数返回NULL,调用方法如下SearchBST1(bt,x,NULL,f);  这里的第3个参数f1仅作中间参数,用于求f,初始设为NULL*/

    {  if(bt==NULL)

      {  f=NULL;

        return (NULL);

      }

      else if(k==bt->key)

      {  f=f1;

        return(bt);

      }

      else if(k<bt->key)

        return SearchBST1(bt->lchild,k,bt,f);        //在左子树中递归查找

      else

        return SearchBST1(bt->rchild,k,bt,f);        //在右子树中递归查找

    }

      二叉排序树的删除

    删除过程分为以下几种情况:(删除操作必须首先进行查找,设在查找结束时p指向要删除的结点)

    (1)若p结点是叶子结点,直接删去该结点。这是最简单的删除结点情况。

    (2)若p结点只有左子树没有右子树。根据二叉排序树的特点,可以直接将其左孩子替代结点p(结点替换)。

    (3)若p结点只有右子树没有左子树。根据二叉排序树的特点,可以直接将其右孩子替代结点p(结点替换)。

    (4)若p结点同时存在左、右子树。根据二叉排序树的特点,可以从左子树中选择关键字最大的结点r,用结点r的值替代结点p的值(结点值替换),并删除结点r(由于r结点一定没有右孩子,删除它属于情况(2)),原理是用中序前驱替代被删结点。

      也可以从其右子树中选择关键字最小的结点r,用结点r的值替代结点p的值(结点值替换),而且将它删除(由于r结点一定没有左子树,删除它属于情况(3))。原理是用中序后继结点替代被删结点。

      首先查找关键字为k的被删结点p.

    bool deletek(BSTNode *&bt,KeyType k)

    {  if (bt!=NULL)

      {  if(k==bt->key)}        //查找到了被删结点bt

        {  deletep(bt);        //调用deletep删除结点bt

          return true;        //成功删除,返回真

        }

        else if(k<bt->key)

          deletek(bt->lchild,k);      //在左子树中查找

        else

          deletek(bt->rchild,k);      //在右子树中查找

      }

      else return false;            //未查找到,返回假

    }

      删除结点p(结点p仅有右子树)

    void deletep(BSTNode *&p)

    {  BSTNode *q;

      q=p;        //让q指向结点p

      p=p->rchild;      //让p指向它的右孩子

      free(q);        //释放结点q的空间

    }

      删除二叉排序树bt中关键字为k的结点

    bool DeleteBST(BSTNode *&bt,KeyType k)        //在bt中删除关键字为k的结点

    {  if(bt==NULL)

        return false;                  //空树删除失败,返回假

       else

      {  if(k<bt->key)

          return DeleteBST(bt->lchild,k);        //递归在左子树中删除为k的结点

        else if (k>bt->key)

          return DeleteBST(bt->rchild,k);        //递归在右子树中删除为k的结点

        else                      //找到了要删除的结点bt

          {  Delete(bt);              //调用Delete(bt)函数删除结点bt

            return true;              //删除成功,返回真

          }

       }

    }

     void  Delete(BSTNode *&p)          //从二叉排序树中删除结点p

    {  BSTNode *q;

      if(p->rchild==NULL)            //结点p没有右子树(含为叶子结点)的情况

      {  q=p;

        p=p->lchild;              //用结点p的左孩子替代它

        free(q);

      }

      else if(p->lchild==NULL)          //结点p没有左子树的情况

      {  q=p;

        p=p->rchild;              //用结点p的右孩子替代它

        free(q);

      }

      else Delete1(p,p->lchild);          //结点p既没有左子树又没有右子树的情况

    }

     void Delete1(BSTNode *p,BSTNode *&r)    //被删结点p有左、右子树,r指向其左孩子

    {  BSTNode *q;

      if(r->rchild!=NULL)            //递归找结点r的最右下结点

        Delete1(p,r->rchild);

      else                  //找到了最右下结点r(它没有右子树)

      {  p->key=r->key;          //将结点r的值存放到结点p中(结点值替代)

        p->data=r->data;

        q=r;              //删除结点r

        r=r->lchild;            //即用结点r的值存放到结点p中(结点值替代)

        free(q);             //释放结点q的空间

      }

    }

     

     

  • 相关阅读:
    面试准备——springboot相关
    面试准备——mybatis相关
    面试准备——struts2和springmvc的区别
    面试准备——Struts2相关问题
    面试准备——springmvc面试题
    面试准备——spring面试题
    面试准备——数据库优化问题
    面试准备——JVM相关
    面试准备——数据结构
    面试准备——多线程
  • 原文地址:https://www.cnblogs.com/li1997/p/8358906.html
Copyright © 2020-2023  润新知