概念:二叉查詢樹(binary search tree) (又:二叉搜尋樹,二叉排序樹)
它或者是一棵空樹,或者是具有下列性質的二叉樹:
若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
它的左、右子樹也分別為二叉排序樹。
當我們對二叉搜尋樹進行中序遍歷時,可以得到乙個關鍵字的有序序列。
插入:
在向二叉搜尋樹中插入節點時
首先需要判斷樹是否存在。
如若是空樹,則直接插入。
如果存在,則對插入的位置進行查詢,在這裡我們不允許相同的鍵值存在。
找到插入位置後,還應判斷是在根節點的左子樹還是右子樹。
節點型別:
template
k>
struct
binarysearchtreenode // 二叉搜尋樹的節點
};
實現
template
class binarysearchtree
);bool insert(const k& key)
node *
parent
=null;
node *cur = _root;
while (cur)
else
if (cur->_key > key)
else
//資料相同,冗餘
return
false;
}if (key <
parent
->_key)
parent
->_left =
new node(key);
else
parent
->_right =
new node(key);
return
true;
}
刪除:
在對搜尋二叉樹進行刪除的時候,我們需要考慮以下情況:
1. 二叉樹是否存在。
2. 要刪除的節點是頁節點。
3. 要刪除的節點的左子樹存在。
4. 要刪除的節點的右子樹存在。
5. 要刪除的節點的左右子樹都存在。
6. 要刪除的節點不存在。
第一種和第六種情況可以直接返回。
第二種情況直接對節點進行刪除。
對於第三種情況:
我們將它的左子樹與該節點的父節點的左/右(該節點所在位置)相連,然後刪除該節點即可。
對於第四中情況的處理方式與第三中相同。
對於第五種情況我們不可以直接對該點進行刪除
我們可以將該點與其左子樹中的最大值進行交換(左子樹的最右樹),然後就像刪除頁節點一樣可以直接進行刪除。
在以上的刪除情況中我們都要對如果刪除的節點是根節點進行判斷,否則程式會出現崩潰情況.
實現:
bool remove(const k& key)
else
if (cur->_key > key)
else
}else
if (cur->_right ==
null)
}else
cur->_key = subleft->_key;
del = subleft;
// 不可以直接讓parent 的左 指向 cur 的右
if (parent
->_left == subleft)
parent
->_left = subleft->_right;
else
parent
->_right = subleft->_left;
}delete del;
return
true;}}
return
false;
}
查詢:
根據左樹比根節點小,右樹比根節點大的特點進行查詢
實現:
node * find(const k& key)
由這張圖我們可以發現,查詢的時間複雜度大致為 o(log(n))
但是,當我們所獲得的搜尋二叉樹是乙個單支樹時,查詢的時間複雜度則會變為 o(n)
所以搜尋二叉樹的時間複雜度大致在 o(log(n))~o(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 ...
樹 二叉樹 二叉搜尋樹
給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 13輸出 true 示例 2 輸入 5 14 3 6輸出 false 解釋 輸入為 ...