二叉搜索树的结构类似于二分查找的思想,在二叉树结构里面,将数据的大小分为树的左右子树,从而在搜索的时候类似于二叉搜索。
如图:
当搜索一个二叉搜索树的时候时间复杂度就是O(logN).
构建搜索二叉树:
BSTree(int *arr,size_t size)
:_root(NULL)
{
int index = 0;
for(int i = 0;i<size;i++)
_GreatNode(_root,arr,index++,size);
}
void _GreatNode(Node* root,int *arr,int index,size_t size){
Node* tmp = new Node(arr[index]);
if(root == NULL){
_root = tmp;
return;
}
int d = arr[index];
Node* parent = NULL;
while(root){
parent = root;
if(d < root->value)
root = root->left;
else
root = root->right;
}
if(d < parent->value)
parent->left = tmp;
else
parent->right = tmp;
}
搜索二叉树的删除
搜索二叉树的删除分为以下几种情况:
- 当删除的搜索二叉树为空树 的时候
- 当删除的搜索二叉树只有右子树的时候
- 当删除的搜索二叉树只有左子树的时候
当删除的搜索二叉树的左右子树都存在的时候
注:这里面的第一种情况可以和第二或者第三种情况进行合并
当二叉搜索树只有左子树的时候:
当二叉搜索树是由右子树的时候:
当二叉搜索树左右孩子都存在的时候:
当二叉搜索树的左右子树都存在的时候就可以在树的左右子树里面寻找一个节点将需要删除的结点的值进行替换,从而去删除那个替换过的结点。
实现代码:
void _Del_Tree(Node* root,int key){
if(NULL == root)
return ;
Node* tmp = find(key);
Node* parent = _find_parent(_root,key);
if(NULL == tmp)
return ;
if(tmp->left == NULL){ //当二叉搜索树的左孩子为空的时候
if(tmp == _root)
_root = tmp->right;
else{
if(tmp == parent->left)
parent->left = tmp->right;
else
parent->right = tmp->right;
}
delete tmp;
}
else if(tmp->right == NULL){ //当二叉搜索树的右孩子为空的时候
if(tmp == _root)
_root = tmp->left;
else{
if(tmp == parent->left)
parent->left = tmp->left;
else
parent->right = tmp->left;
}
delete tmp;
}
else{
Node* pkey = NULL;
//先寻找所有孩子里面可以替换的孩子节点
if(tmp->left->right){
pkey = tmp->left->right;
parent = tmp->left;
}
if(tmp->right->left){
pkey = tmp->right->left;
parent = tmp->right;
}
//当没有找到可以替换的节点的时候直接进行交换删除
if(pkey == NULL){
swap(tmp->value,tmp->right->value);
Node* del = tmp->right;
tmp->right = del->right;
delete del;
}
else{ //当找到可以交换的孩子节点的时候将节点进行交换,然后继续向下删除交换的节点
swap(pkey->value,tmp->value);
_Del_Tree(root,key);
}
}
}