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

posted @ 2011-08-24 00:02  xiaodongrush  阅读(7463)  评论(5编辑  收藏  举报