二叉排序树研究

来源:互联网 发布:mac内网聊天工具 编辑:程序博客网 时间:2024/06/02 02:16

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

(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;}
结果有图为证:




0 0