二叉搜索树-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; // 失败
}
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* pre = NULL;
BSTNode* curr = root;
while(curr != NULL) {
if(value < curr->value) { // 向左
pre = curr;
curr = curr->left;
while(curr != NULL) {
if(value < curr->value) { // 向左
pre = curr;
curr = curr->left;
}
else if(value > curr->value) { // 向右
pre = curr;
curr = curr->right;
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)
else // 失败
return false;
}
curr = new BSTNode; // 插入
curr->value = value;
curr->left = curr->right = NULL;
if(pre == NULL)
root = curr;
else
else
curr->value < pre->value ? pre->left=curr : pre->right=curr;
return true;
}
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; // 失败
}
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