大话数据结构---(七)二叉排序树

1.定义

二叉排序树,又称二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树。

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结构的值。
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
  • 它的左、右子树也分别为二叉排序树。
    构造二叉排序树的目的,其实并不是为了排序,而是为了提高查找和插入删除关键字的速度。

2.二叉排序树查找操作

首先我们提供一个二叉树的结构。

typedef struct BiTNode//结点结构
{ 
   int data;
   struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

然后我们来看看二叉排序树的查找是如何实现的。

/*递归查找二叉排序树T中是否存在key
  指针f指向T的双亲,其初始调用值为NULL
  若查找成功,则指针p指向该数据元素结点,并返回TRUE
  否则指针p指向查找路径上访问的最后一个结点并返回FALSE*/
Status SearchBST(BiTree T,int key,BiTree f,BiTree *p)
{ 
   if(!T)//查找不成功
   {
     *p=f;
     return FALSE;
   }
   else if(key==T->data)//查找成功
   {
     *p=T;
     return TRUE;
   }
   else if(key<T->data)
     return SearchBST(T->lchild,key,T,p);//在左子树继续查找
   else
     return Search(T->rchild,key,T,p);//在右子树继续寻找
}

3.二叉排序树插入操作

有了二叉排序树的查找函数,那么所谓的二叉排序树的插入,其实也就是将关键字放到树中的合适位置而已,来看代码。

/*当二叉排序树T中不存在关键字等于key的数据元素时,
  插入key并返回TRUE,否则返回FALSE*/
Status InsertBST(BiTree *T,int key)
{
  BiTree p,s;
  if(!Search(*T,key,NULL,&p))//查找不成功
  {
    s=(BiTree)malloc(sizeof(BiTNode));
    s->data=key;
    s->lchild=s->rchild=NULL;
    if(!p)
      *T=s;
     else if(key<p->data)
      p->lchild=s;//插入s为新的根结点
     else
      p->rchild=s;//插入s为右孩子
     return TRUE;
  }
  else
   return FALSE;//树中已有关键字相同的结点,不再插入
}

4.二叉树排序树的删除操作

我们已经介绍了二叉排序树的查找与插入算法,但是对于二叉排序树的删除,就不是那么容易了,我们不能因为删除了结点,而让这棵树变得不满足二叉排序树的特性,所以删除需要考虑多种情况,如图1、2、3。
大话数据结构---(七)二叉排序树_第1张图片这里对三种情况进行分析:

  • 图1情况,删除叶结点,可直接删除,无需其它操作。
  • 图2情况,将该结点的右子树直接接到该结点双亲结点的右子树。
  • 图3情况,将该结点左子树的最大值的结点给该结点赋值,然后删除最大值的结点。
    下面给出代码:
Status Delete(BiTree *p)
{
  BiTree q,s;
  if((*p)->rchild==NULL)//右子树空则需要重接它的左子树
  { 
    q=*p;*p=(*p)->lchild;free(q);
  }
  else if((*p)->lchild==NULL)//只需要重接它的右子树
  {
    q=*p;s=(*p)->lchild;
    while(s->rchild)//转左,然后向右到尽头(找到待删结点的前驱)
    {
      q=s;s=s->rchild;
    }
    (*p)->data=s->data;//s指向被删结点的直接前驱
    if(q!=*p)
      q->rchild=s->lchild;//重接q的右子树
    else
      q->lchild=s->child;//重接q的左子树
    free(s);
  }
  return TRUE;
}

5.总结

总之,二叉排序树是以链接的方式存储,保持了链接存储结构在执行插入或删除操作时不用移动元素的优点,只要找到合适的插入或删除位置后,仅需修改链接指针即可。插入删除的时间性能的时间性能比较好。

你可能感兴趣的:(数据结构)