二叉搜尋樹又稱二叉排序樹,它或者是一棵空樹,或者是具有以下性質的二叉樹:二叉搜尋樹的查詢:
//非遞迴查詢
node*
find
(const k& key)
else
if(cur-
>_key > key)
else
}return
nullptr;}
//遞迴查詢
node*
_findr
(node* root,
const k& key)
if(root-
>_key == key)
else
if(root-
>_key < key)
else
if(root-
>_key > key)
} node*
findr
(const k& key)
二叉搜尋樹的插入://遞迴插入
bool
_insertr
(node*
& root,
const k& key)
//加上引用才可以插入進去
if(root-
>_key < key)
else
if(root-
>_key > key)
else
}bool
insertr
(const k& key)
//非遞迴插入
bool
insert
(const k& key)
node* cur = _root;
node* parent =
nullptr
;//注意要在這裡定義乙個parent儲存前乙個結點,最後在連線上才能實現插入
while
(cur)
else
if(cur-
>_key > key)
else
} cur =
newnode
(key);if
(parent-
>_key < key)
else
return
true
;}
注意(可以看上述**實現):
二叉搜尋樹的刪除:
首先查詢元素是否在二叉搜尋樹中,如果不存在,則返回, 否則要刪除的結點可能分下面四種情況:
其實上面四種情況總體上來算就只有三種情況,因為 a 情況可以算是 b 或者 c 情況。則刪除方法只有三種分別為:
else
if(cur-
>right ==
nullptr
)else
else
}}
其中又有兩種情況:
①:被刪除節點的父親結點的左孩子是該刪除結點(比如下圖要刪除 1 )
②:被刪除節點的父親結點的右孩子是該刪除結點(比如下圖刪除 7 )
此外,還應該注意,剛開始要判斷刪除的結點的父親是否為空,防止根節點的左孩子為空且要刪除根節點的時候,後面對 parent 操作會出錯,比如 要刪除 5, 5 是根節點,此時就應該直接 將 7 作為根節點(後附**):
//這裡的 lessparent 不能為初始化為空,應該考慮循壞如果不進去的時候就會出錯
node* lessright = cur-
>right;
while
(lessright-
>left)
cur-
>_key = lessright-
>_key;
del = lessright;
if(lessparent-
>left == lessright)
//用來替換應該刪除結點的結點可能還有右孩子
else
整個實現完整源**:
template
<
class
k>
struct bstreenode};
template
<
class
k>
class
bstree
//遞迴插入
bool
_insertr
(node*
& root,
const k& key)
//加上引用才可以插入進去
if(root-
>_key < key)
else
if(root-
>_key > key)
else
}bool
insertr
(const k& key)
//非遞迴插入
bool
insert
(const k& key)
node* cur = _root;
node* parent =
nullptr
;//注意要在這裡定義乙個parent儲存前乙個結點,最後在連線上才能實現插入
while
(cur)
else
if(cur-
>_key > key)
else
} cur =
newnode
(key);if
(parent-
>_key < key)
else
return
true;}
//中序遍歷
void
inorder()
//呼叫遞迴時候,需要再次定義乙個_inorder(),因為物件在類外面無法傳參
void
_inorder
(node* root)
_inorder
(root-
>left)
; cout << root-
>_key <<
" ";
_inorder
(root-
>right);}
//非遞迴查詢
node*
find
(const k& key)
else
if(cur-
>_key > key)
else
}return
nullptr;}
//遞迴查詢
node*
_findr
(node* root,
const k& key)
if(root-
>_key == key)
else
if(root-
>_key < key)
else
if(root-
>_key > key)
} node*
findr
(const k& key)
//刪除
bool
erase
(const k& key)
else
if(cur-
>_key > key)
else
else
else}}
//2.右為空(裡面也包含兩種小情況)
else
if(cur-
>right ==
nullptr
)else
else}}
//3.左右都不為空
else
cur-
>_key = lessright-
>_key;
del = lessright;
if(lessparent-
>left == lessright)
//用來替換應該刪除結點的結點可能還有右孩子
else
}delete del;
return
true;}
}return
false;}
private
: node* _root;
};
二叉搜尋樹的模擬實現與總結
二叉搜尋樹又稱二叉排序樹。空樹也是一顆二叉搜尋樹 搜尋二叉搜尋樹的中序遍歷一定是乙個有序的資料集合。二叉搜尋樹的最左邊節點一定是最小的節點。二叉搜尋樹的最右邊節點一定是最大的節點。二叉搜尋樹的插入和刪除都必須先查詢,因此,查詢效率便代表了二叉搜尋樹中各個操作的效能。假設有乙個n個節點的二叉搜尋樹,若...
二叉搜尋樹 二叉搜尋樹
題目 二叉搜尋樹 time limit 2000 1000 ms j a others memory limit 32768 32768 k j a others total submission s 6945 accepted submission s 3077 problem descripti...
二叉搜尋樹 修剪二叉搜尋樹
第一反應是重構,看來別人的解答發現,其實不用重構那麼複雜。treenode trimbst treenode root,int low,int high if root val high 下一層處理完左子樹的結果賦給root left,處理完右子樹的結果賦給root right。root left ...