二叉搜索树-BST-查找算法-插入算法-删除算法

1. 简述

    最近打算复习一下,几个经典的树结构,本文主要关注二叉搜索树,英文名称为Binary Search Tree (简称BST)。
    本文主要总结二叉搜索树的查找算法、插入算法和删除算法。

2. 查找算法

    这个比较简单,要么找到了,要么向左,要么向右。 

BSTNode *  bst_search(BSTNode *  node,  int  value) {
  
while (node  !=  NULL) {
    
if (value  <  node -> value)  //  向左 
      node  =  node -> left;
    
else   if (value  >  node -> value)  //  向右 
      node  =  node -> right;
    
else   //  找到 
       return  node;
  }
  
return  NULL;  //  失败 
}

3.  插入算法

     这个也不难,首先找到插入的位置,要么向左,要么向右,直到找到空结点,即为插入位置,如果找到了相同值的结点,插入失败。 

bool  bst_insert(BSTNode *&  root,  int  value) {
  BSTNode* pre = NULL;
  BSTNode* curr = root;
  
while (curr  !=  NULL) {
    
if (value  <  curr -> value) {  //  向左 
      pre = curr;
      curr 
=  curr -> left;
    }
    
else   if (value  >  curr -> value) { //  向右 
      pre = curr;
      curr 
=  curr -> right;
    }
    
else   //  失败 
       return   false ;
  }
  curr 
=   new  BSTNode;  //  插入 
  curr -> value  =  value;
  curr
-> left  =  curr -> right  =  NULL;
  if(pre == NULL)
    root = curr;
  else
    curr->value < pre->value ? pre->left=curr : pre->right=curr;
  
return   true ;
}

4. 删除算法

    相对查找和插入复杂一点,根据待删除结点的孩子情况,分三种情况:没有孩子,只有一个孩子,有两个孩子。
    没有孩子的情况,其父结点指向空,删除该结点。
    有一个孩子的情况,其父结点指向其孩子,删除该结点。
    有两个孩子的情况,当前结点与左子树中最大的元素交换,然后删除当前结点。左子树最大的元素一定是叶子结点,交换后,当前结点即为叶子结点,删除参考没有孩子的情况。另一种方法是,当前结点与右子树中最小的元素交换,然后删除当前结点。
    代码实现分别考虑三种情况,并且每种情况考虑了待删除结点是不是根结点。虽然实现啰嗦了一些,不过情况考虑的周全,对于入门算是够了。 

bool  bst_delete(BSTNode *&  node,  int  value) {
  BSTNode
*  parent  =  NULL;
  BSTNode
*  tmp;
  
while (node  !=  NULL) {
    
if (value  <  node -> value) {  //  向左 
      parent  =  node;
      node 
=  node -> left;
    }
    
else   if (value  >  node -> value) {  //  向右 
      parent  =  node;
      node 
=  node -> right;
    }
    
else  {  //  找到了 
       if (NULL == node -> left  &&  NULL == node - right) {  //  叶子结点         
         if (parent  ==  NULL) {  //  根结点 
          delete node;
          node 
=  NULL;
        }
        
else  {  //  非根结点 
          (parent -> left == node) ? (parent -> left = NULL):(parent -> right = NULL);
          delete node;
          node 
=  NULL;
        }        
      }
      
else   if (NULL != node -> left  &&  NULL == node -> right) {  //  只有左孩子
         if (parent  ==  NULL) {  //  根结点 
          tmp  =  node;
          node 
=  node -> left;
          delete tmp;          
        }
        
else  {  //  非根结点 
          (parent -> left == node) ? (parent -> left = node -> left):(parent -> right = node -> left);
          delete node;
        }
      }
      
else   if (NULL != node -> right  &&  NULL == node -> left) {  //  只有右孩子 
         if (parent  ==  NULL) {  //  根结点 
          tmp  =  node;
          node 
=  node -> right;
          delete tmp;          
        }
        
else  {  //  非根结点 
          (parent -> left == node) ? (parent -> left = node -> right):(parent -> right = node -> right);
          delete node;
        }
      }
      
else  {  //  既有左孩子也有右孩子 
        BSTNode *  leftNode  =  node;
        
while (leftNode -> right  !=  NULL) {
          parent 
=  leftNode;
          leftNode 
=  leftNode -> right;
        }
        
//  交换leftNode与node
         int  swapValue  =  leftNode -> value;
        leftNode
-> value  =  node -> value;
        node
-> value  =  swapValue;
        
//  删除leftNode,parent肯定不为空 
        (parent -> left == node) ? (parent -> left = NULL):(parent -> right = NULL);
        delete node;
      }
    }
  }
  
return   false //  失败
}

5. 参考

    百度百科_二叉搜索树    http://baike.baidu.com/view/389453.htm  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值