二分搜索樹是一種設計良好的有序集合,在平衡的情況下,查找search,插入insertion,刪除deletion都具有O(logn)的計算時間。本文討論實現二分搜索樹的具體細節。
二分搜索樹的每個結點包含key域,以及至多兩個孩子結點,並且左孩子小於當前結點的值,右孩子大於當前結點值。為了方便操作,每個結點還需要維護父結點的信息。從上面的描述可以看出,二分搜索樹的任何一個子樹同樣也是二分搜索樹。
搜索操作是所有操作的基礎。搜索操作可以很容易用遞歸過程描述:key>cur.key,則搜索右子樹;key<cur.key,則搜索左子樹;key==cur.key或者遇到空節點,則退出。
1 bool ST_BST::search(int val, ST_BST_Node* cur_node)
2 {
3 bool isFind=false;
4 if(cur_node==nullptr)
5 {
6 printf("Search failed for node with value %d\n", val);
7 return isFind;
8 }
9
10 if(cur_node->value==val)
11 {
12 isFind=true;
13 }
14 else if(val < cur_node->value)
15 {
16 isFind=search(val, cur_node->left);
17 }
18 else
19 {
20 isFind=search(val, cur_node->right);
21 }
22
23 return isFind;
24 }
插入操作找到需要插入的位置,然後創建結點,並加入該樹。
void ST_BST::insert(int val,ST_BST_Node* cur_node)
{
if(val < cur_node->value)
{
if(cur_node->left==nullptr)
{
cur_node->left=createNode(val,cur_node);
}
else
{
insert(val, cur_node->left);
}
}
else if(val > cur_node->value)
{
if(cur_node->right==nullptr)
{
cur_node->right=createNode(val,cur_node);
}
else
{
insert(val, cur_node->right);
}
}
}
刪除操作相對於前面兩個操作稍顯複雜。
(1)假如刪除的結點有兩個孩子,則需要搜索該結點的後繼結點successor或者前驅結點predecessor來替換到該結點,然後再刪除successor或者predecessor. 其中successor是待刪除結點右子樹中最小的結點,而predecessor則是左子樹中最大的結點。
(2)