二叉排序树研究

    数据结构中的二叉排序树研究,做个记录。

(1)二叉排序树概念(二叉查找树)

它是一颗空树,或者具有以下性质的二叉树。

a、若它的左子树不为空,则左子树上所有结点值均小于它的根结点的值

b、若它的右子树不为空,则左子树上所有结点值均大于它的根结点的值

c、左右子树有分别是二叉排序树

(2)二叉排序树查找操作

二叉排序树结点结构体:

typedef struct BiTNode          //结点结构体
{
   int data;
   struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
查找代码如下:

/*********************************************
**功能:递归查找二叉排序树中是否存在key
**T:二叉排序树
**key:键值
**f:指向T的双亲
**p:如果查找成功  指向该数据元素结点       否则指向查找路径上访问的最后一个结点,并返回一个false
*********************************************/
int SearchBST(BiTree T,int key,BiTree f,BiTree *p)
{
   if (!T)        //查找不成功
   {
      *p = f;
      return 0;
   }
   else if (key == T->data)          //找到了键值
   {
      *p = T;
      return 1;
   }
   else if (key < T->data)           //左子树继续查找
   {
     return SearchBST(T->lchild,key,T,p);      
   }
   else                             //右子树中继续查找
   {
      return SearchBST(T->rchild,key,T,p);      
   }
}
(3)二叉排序树插入操作
/*********************************************
**功能:二叉排序树插入操作,如果二叉排序树中不存在关键字等于key的数据元素时,插入key并返回true,否则返回false
**T:二叉排序树
**key:关键字
*********************************************/
int InsertBST(BiTree *T,int key)
{
   BiTree  p,s;           //两个临时变量,p指向查找路径上的最后一个结点;s用于新插入的结点
   if (!SearchBST(*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;
      }
      else                         //插入到右子树
      {
         p->rchild = s;
      }
      return 1;
   }
   else
   {
      return 0;
   }
}
(4)二叉排序树删除操作

删除操作稍微麻烦写,分三种情况讨论

a、待删除结点是叶子结点(直接删除)

b、待删除结点仅有左或者右子树(子承父业)

c、待删除结点左右子树同时存在(找到待删除结点的直接前驱,用直接前驱替换当前点,然后重接左或右子树)

代码如下:

/*********************************************
**功能:二叉排序树删除操作,如果二叉排序树中存在关键字等于key的数据元素时,删除该数据元素结点,并返回true,否则返回false
**T:二叉排序树
**key:关键字
*********************************************/
int DeleteBST(BiTree* T,int key)
{
   if (! *T)    //不存在关键字等于key的数据元素
   {
      return 0;
   }
   else
   {
      if (key == (*T)->data)             //找到关键字等于key的结点
      {
         return Delete(T);
      }
      else if (key < (*T)->data)
      {
         return DeleteBST(&(*T)->lchild,key);      
      }
      else
      {
         return DeleteBST(&(*T)->rchild,key);
      }
   }
}
真正执行删除操作的是Delete()函数,代码如下:

/*********************************************
**功能:二叉排序树中删除结点p,并重接左右子树
**p:待删除的结点
*********************************************/
int Delete(BiTree *p)
{
   //分三种情况讨论:待删除的结点  1、叶结点  2、仅有左或右子树  3、左右子树同时存在
   BiTree q,s;
   if (!(*p)->rchild)      //如果右子树为空,只需要重接左子树即可
   {
      q = *p;               //暂存
      *p = (*p)->lchild;    //覆盖
      free(q);              //删除
   }
   else if (!(*p)->lchild)    //如果左子树为空,只需要重接右子树即可
   {
      q = *p;               //暂存
      *p = (*p)->rchild;    //覆盖
      free(q);              //删除
   }
   else
   {
      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->lchild;     //重接q的左子树
      }
      free(s);
   }
   return 1;
}

测试如下:

/*********************************************
**功能:二叉排序树删除操作,如果二叉排序树中存在关键字等于key的数据元素时,删除该数据元素结点,并返回true,否则返回false
**T:二叉排序树
**key:关键字
*********************************************/
int DeleteBST(BiTree* T,int key)
{
   if (! *T)    //不存在关键字等于key的数据元素
   {
      return 0;
   }
   else
   {
      if (key == (*T)->data)             //找到关键字等于key的结点
      {
         return Delete(T);
      }
      else if (key < (*T)->data)
      {
         return DeleteBST(&(*T)->lchild,key);      
      }
      else
      {
         return DeleteBST(&(*T)->rchild,key);
      }
   }
}

/*********************************************
**功能:递归打印二叉树,中序遍历
**T:二叉排序树
*********************************************/
void PrintBTree(BiTree T)
{
   if (!T)                    //递归出口
      return;
   PrintBTree(T->lchild);
   printf("%d\t",T->data);
   PrintBTree(T->rchild);
}
int _tmain(int argc, _TCHAR* argv[])
{
   int a[] = {62,88,58,47,35,73,51,99,37,93};
   BiTree T = NULL;
   for (int i=0;i<10;++i)
   {
      InsertBST(&T,a[i]);
   }
   PrintBTree(T);
   DeleteBST(&T,58);
   PrintBTree(T);
   return 0;
}
结果有图为证:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值