二叉树的应用---1.二叉搜索树

(一)二叉搜索树的定义:

该树的每一个结点都有一个作为搜索依据的关键码,对于任意结点而言,其左子树上的结点的关键码均小于右子树的关键码,如图所示
在这里插入图片描述

(二)二叉搜索树的查找:

常用的算法是分割查找法:
思想:1.若根结点的关键码等于查找的键值
2.若键值小于根结点的关键码的值,则继续在左子树中查找,若键值大于结点的关键码值,则继续在右子树中寻找

template<class T>
BinarySearchTreeNode<T>*BinarySearchTree<T>::search(BinarySearchTreeNode<T>*root,T key)
{
    BinarySearchTreeNode<T>*current=root;
    while(NULL!=root)&&(key!=current->getValue()){
    //根据当前结点的值的大小决定移动方向
    current=(key<current->getvalue()?search(current->getLeftChild(),key):search(current->getRightChild(),key));     
    }
    return current;
  }

(三)二叉搜索树的插入:

思路:从根开始,将要插入的结点的关键码和树中的每一个结点的关键码比较,如果大于该结点的关键码,则下一个比较的位置移动到该结点的右子结点处:

template<class T>
void BinarySearchTree<T>::insertNode(const T& value){
      BinarySearchTreeNode<T>*o=root,*prev=NULL;
      while(p!=0){            //新结点查找位置
         prev=p;               //记录父结点
         if(p->getValue()<value)
              p=p->getRightChild();
         else
              p=p->geLeftChild();
         }
     if(root==NULL)           //若为空树,则将新结点作为根结点
             root=new BinarySearchTreeNode<T>(value);
     else if(prev->getValue()<value)              //根据关键码设置左右结点
             prev->setRightChild(new BinarySearchTreeNode<T>(value));
     else if(prev->getVaule()>value)
             prev->setLeftChild(new BinarySearchTreeNode<T>(value));
      }

(四)二叉搜索树的删除:

二叉树的删除有三种情况:

  • 1.被删除的结点无子树,则直接删除
    在这里插入图片描述

  • 2.被删除的结点有一个子树,则将唯一子树的根结点替换要删除的结点;
    在这里插入图片描述

  • 3.若被删除的结点有两个子树,则有两种办法来删除

合并删除:

查找到的被删除结点的P的左子树按中序遍历最后一个结点r,将r的右指针赋值为指向结点p的右子树的根。然后用结点p的左子树的根代替被删除的结点p,最后删除结点p

在这里插入图片描述

template<class T>
void BinarySearchTree<T>::deleteByMerging(BinarySearchTreeNode<T>*node){
    BinarySearchTreeNode<T>*temp=node;
    if(node!=NULL){
        if(!node->getRightChild()){    //如果被删除的没有右子树,则用左子树结点代替
            node=node->getLeftChild();
         else if(node->getLeftChild()==NULL){     //如果没有左子树,则用右子树结点代替
           node=node->getRightChild();
         else{              //如果左右子树都存在
            tmp=node->getLeftChild();
            while(tmp->getRightChild()!=NULL)   //查找左子树中序遍历的最后一个结点
            tmp=tmp->getRightChild();     //把查找到的结点的右指针赋值给要删除的结点的右节点
            tmp->setRightChild(node->getRightChild());
            tmp=node;
            node=node->getLeftChild();     //用左子树根结点代替要删除的结点
            }
       if(root==tmp){      //如果要删除的是根结点,则改变根结点
          root=node;
          }
        else{
            //找到父节点后,调整父结点的左右指针
            BinarySearchTreeNode<T>*current=getParent(tmp);
            if(current->getLeftChild()==tmp){
               current->setLeftChild(node);
              }
             else{
                current->setRightChild(node);
                }
           }
           tmp->setLeftChild(NULL);
           tmp->setRightChild(NULL);
           delete tmp;
         }
}

复制删除:

选取一个结点r,将该结点赋值给p并删除结点r
r的选取:选取p的左子树的最大码或右子树的最大码,若r有左子树或者右子树,则将唯一的子树放置到r 在这里插入图片描述

template<class T>
void BinarySearchTreeNode<T>::deleteByCopying(BinarySearchTreeNode<T>*node{
   BinarySearchTreeNode<T>*previous,*tmp=node; 
    //如果被删除的结点没有右子树,则用左子树代替要删除的结点
   if(node->getRightChild()==NULL)
      node=node->getLeftChild();
     //如果要删除的没有左子树,则用右子树代替
   else if(node->getLeftChild()==NULL)
      node=node->getRightChild();
         //如果两者都有
    else{
         tmp=node->getLeftChild();
         previous=node;
              //查找左子树的最大码
         while(temp->getRightChild()!=NULL){
          previous=tmp;
          temp=temp->getRightChild();
          }
               //将找到的结点赋值
      node->setValue(tmp->getValue());
      if(previous==node)
            previous->setLeftChild(tmp->getLeftChild());
      else
            previous->setRightChild(tmp->getLeftChild());
       }
      delete tmp;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值