二叉搜索树-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  

    原文作者:xiaodongrush
    原文地址: https://www.cnblogs.com/pangxiaodong/archive/2011/08/24/2151060.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞