二叉搜索树

        概念:二叉排序树也叫二叉搜索树,1.若它的左子树非空,则左子树上所有结点的值均大于根结点的值。2.若它的右子树非空,则右子树上所有结点的值均大于根结点的值 3.它的左右子树也叫二叉排序树


二叉排序树的查找:

        二叉排序树中value的结点。
1.从根结点开始,设p指向根结点。
2.将value与p结点的关键字进行比较,若俩者相等,则查找成功;若value值较小,则在p的左子树中继续查找;若value值较大,则在p的右子树中继续查找
3.重复执行上一步,直到查找成功或p为空。若p为空,则查找不成功。
一次查找经过从根结点到某结点的一条路径而不需要遍历整棵树,若查找成功则到达指定结点,否则经过某个叶子结点。因此二叉排序树能够提供快速查找。



二叉排序树的插入:

        一颗二叉排序树插入结点之后必须任然是二叉排序树。每插入一个结点,首先需要找到该结点在二叉排序树中的位置,若具有相同关键字的结点已在二叉排序树中,则不插入;否则将新结点作为叶子结点,链接在其查找不成功时的一条路径之尾,该路径从根结点到某个原叶子结点。


二叉排序树的删除:

在二叉排序树种删除一个结点,首先查找该结点,若存在,则根据二叉排序树不同程度的调整,使删除结点的二叉树仍然是二叉排序树。设p是待删除的结点,parent指向p的父母结点。根据p结点的度不同,分暗中情况。
1.p是叶子结点。若p是parent的左孩子,删除p结点并设置parent的left链为空。
2.p是度为1的结点,删除p结点并用p的孩子填补作为parent的孩子,
若p是parent的左孩子且p有左孩子,设置parent的left链指向p的左孩子
若p是parent的左孩子且p有右孩子,设置parent的left链指向p的右孩子
若p是parent的右孩子且p有左孩子,设置parent的right链指向p的左孩子
若p是parent的右孩子且p有右孩子,设置parent的left链指向p的右孩子
3.p为度为2的结点,不直接删除p结点,而是首先用p在中根次序下的后继结点innext值代替p结点值,再删除innext结点,这样讲删除度为2的结点的问题转化为删除度为1的结点或叶子结点,使得对二叉排序树的调整减少到最小程度。


#include "BinaryTree.h"   //二叉链表的二叉树类
template <class T>
class BinarySortTree : public BinaryTree<T>  //二叉排序树类,继承二叉树类
{
    public:
           BinarySortTree ():BinaryTree<T> () {}  //构造空二叉排序树,调用基类构造函数
     ~BinarySortTree ()  {}  
          DoubleNode <T>*Search (T value);//查找首次出现值为value的结点
          DoubleNode<T> *Insert (T value);  //插入
          bool Remove (T value);  //删除
          DoubleNode<T>*SearchNode (T value);  //  查找值为value的结点
          bool InsertNode(T value);  //插入结点,非递归算法
    private:
          DoubleNode<T>* Insert (DoubleNode <T>*p, T value);   // 将value插入到以p为根的子树中
          bool Remove (T value, DoubleNode <T> *p,DoubleNode<T> *parent);  //在以p为根的子树中删除value
          DoubleNode<T> *SearchNode (DoubleNode<T>  *p, T value);

};


template <class T>
DoubleNode<T> *BinarySortTree<T>::Search(T value)  //查找首次出现值value的结点
{
    DoubleNode<T> *p=this->root;
    while(p! = NULL && p->data! = value)  //当没有相等者
{
    cout<<p->data <<"?";  //显示查找经过的结点值,可省略
if(value<p->data)  //若value较小
p = p->prior;//进入左子树
    else
       p = p->next;  //进入右子树
}
return p;
}

template<class T>
DoubleNode<T>*  BinarySortTree<T>::Insert (T value)  //插入结点,不插入关键字重复的结点
{
  if(this->root == NULL)
  {
      this->root = new DoubleNode<T> (value);
  return this->root;
  }
    return Insert (this ->root, value);   //插入value到以root为根的二叉排序树中
}


template <class T>
DoubleNode<T>* BinarySortTree<T>::Insert(DoubleNode<T> *p, T value) //将value插入到以p为根的子树中
{
    DoubleNode<T>* q=NULL;
if(p->data == value)
return NULL;
if(value<p->data)
  if(p->prior == NULL)
  {
     q = new DoubleNode<T> (value);
 p->prior = q;
 return q;
  }
  else
  return Insert (p->prior, value);
else
if(p->next == NULL)
{
  q = new DoubleNode<T> (value);
  p->next = q;  //建立叶子结点作为p的右孩子
    return q;
}
else
return Insert(p->next, value);
}

template <class T>
bool BinarySortTree<T>::Remove(T value)
{
   return this->root!=NULL&&Remove (value, this->root,NULL);
}

template <class T>
bool BinarySortTree<T>::Remove(T value, DoubleNode<T> *p, DoubleNode<T> *parent)
                           //在以p为根的子树中删除value,parent是p的父母结点,递归算法
{
   if(value<p->data)
   return Remove(value, p->prior,p);
   else
   if(p->prior!=NULL&&p->next!=NULL)  //p是度为2的结点
   {
      DoubleNode<T>* innext =p->next;
  while(innext -> prior!= NULL)
  innext = innext->prior;
  p->data = innext->data;
  return Remove (p->data,p->next,p);
        }
   else
   {
     if(parent ==NULL)
 {
    if(p->prior!=NULL)
this->root = p->prior;
else
this->root = p->next;
return true;
 }
 if(p==parent ->prior)
 if(p->prior!=NULL)
 parent->prior = p->prior;
 else
 parent->prior = p->next;
 else
 if(p->prior! = NULL)
 parent ->next = p->prior;
 else
 parent ->next = p->next;
 return true;
   }
   return flase;
}

#define _CRT_SECURE_NO_WARNINGS
#include<iostream.h>
#include"BinarySortTree.h"
int main()
{
   const int N = 16;
   int keys[] ={54,18,66,87,36,12,54,81,15,76,57,6,40,99,85,99};
   cout<<"插入:";
   BinarySortTree<int> bstree;
   for(int i=0;i<N;i++)
   if(bstree.Insert(keys[i])!=NULL)
   cout<<keys[i]<<"  ";
   cout<<endl;
   bstree.midRoot();
   cout<<"查找"<<keys[N-1]<<","<<(bstree.SearchNode(keys[N-1])!=NULL?"":"不")<<"成功\n";
   cout<<"查找50,"<<(bstree.SearchNode(50)!=NULL?" ":"不")<<"成功\n";
   return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值