二分搜索树是一种设计良好的有序集合,在平衡的情况下,查找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 ", 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)