二叉搜索樹的結構類似於二分查找的思想,在二叉樹結構裏面,將數據的大小分爲樹的左右子樹,從而在搜索的時候類似於二叉搜索。
如圖:
當搜索一個二叉搜索樹的時候時間複雜度就是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);
}
}
}