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