二元搜尋樹

Root node為8
二叉搜索樹（binary search tree，簡稱BST）是一種有根二叉樹數據結構。它要求每個內部節點的鍵值都大於其左子樹中所有節點的鍵值，且都小於其右子樹中所有節點的鍵值。該樹各項操作時間複雜度均與樹的高度成線性關係。
二叉搜索樹每次比較都能排除大約一半的剩餘節點，故能以對數時間查找、插入、刪除數據。但其性能依賴於節點的插入順序，插入隨機鍵值時仍能維持對數級別，但在最壞情況下會退化成鏈表。為保證效率，研究者發明了多種平衡樹，能將最壞查找複雜度維持在。
二叉搜索樹最早由多位研究者獨立提出，1960年被用來解決帶標籤數據的存儲問題。其還可用來實現Tree sort及優先隊列。

**歷史**
二叉搜索樹最早由多位研究者獨立提出，包括P.F.溫德利、安德魯·唐納德·布思、安德魯·科林、托馬斯·N·希巴德。Culberson1986這種數據結構常被歸功於Conway Berners-Lee及David Wheeler (computer scientist)，他們在1960年將之用於磁帶上帶標籤數據的存儲。Windley1960希巴德實現二叉搜索樹的方法也是最早廣為流傳的一種。Culberson1989
若按任意順序插入節點，樹的高度可能接近節點數，導致操作效率急劇下降。研究者們發明了平衡樹（即能夠自平衡的二叉搜索樹），將樹的高度限制在以內。pp=458–459同時，相關人員也提出了多種高度平衡的二叉搜索樹結構，例如AVL樹、樹堆、紅黑樹等。nist-01其中，AVL樹是首類平衡樹，toronto-01由格奧爾吉·阿杰爾松-韋利斯基及葉夫根尼·蘭迪斯於1962年發明，用於高效組織信息。Adelson-Velsky1962

**性質**
二叉搜索樹為有根的二叉樹，其節點順序為嚴格全序關係，每個節點都滿足：左子樹上所有節點的鍵值都小於該節點，右子樹上所有節點的鍵值都大於該節點。這一結構保證可以在對數時間內定位任意鍵值。p=298除查找外，其也常用於排序，但性能取決於節點的插入和刪除順序——在最壞情況下，連續操作可能使樹退化為類似單鏈表的結構，這時的查找複雜度與鏈表相同。pp=299-302

**遍歷**
二叉搜索樹的遍歷有三種基本方法：前序、中序、後序。p2=162- 中序遍歷：依次遍歷左子樹、根節點、右子樹。遍歷結果為鍵值遞增順序。- 前序遍歷：依次遍歷根節點、左子樹、右子樹。- 後序遍歷：依次遍歷左子樹、右子樹、根節點。
以下是遞歸實現的遍歷偽代碼：p2=162

**操作**

**搜索**
在二叉搜索樹中查找某個特定的鍵，可以使用遞歸或迭代方式實現。
查找過程從樹的Root node開始：- 如果根節點為空（），說明該鍵不存在。- 如果根節點的鍵值與目標鍵值相等，返回該節點，表示查找成功。- 如果目標鍵值小於根節點的鍵值，則繼續在左子樹中查找；- 如果目標鍵值大於根節點的鍵值，則繼續在右子樹中查找。
重複上述步驟，直到找到該鍵，或者剩餘子樹為空。若到達空子樹仍未找到，說明該鍵不存在於樹中。p2=163

**遞歸搜索**
以下偽代碼展示遞歸方式實現的查找過程：p2=163
遞歸會一直進行，直到遇到或是找到目標鍵。

**迭代搜索**
遞歸過程也可展開為循環形式，一般情況下循環版本的效率更高。其偽代碼如下：p2=163
由於查找可能會一直到葉節點，因此時間複雜度為樹的高度（為樹的高度）。p2=163在最壞情況下，一棵嚴重不平衡的二叉搜索樹可能退化成單鏈表，這時複雜度會達到（為樹中節點總數）。但對於高度平衡的二叉搜索樹而言，複雜度為。pp=458–459

**後繼與前驅**
在某些場景下，需要查找給定節點的「後繼」或「前驅」。後繼節點是大於該節點鍵值的節點中，鍵值最小的那一個；前驅節點是小於該節點鍵值的節點中，鍵值最大的那一個。以下偽代碼給出求節點的後繼與前驅方法：lmu-01
尋找樹中鍵值最大或最小的節點，是尋找後繼與前驅過程中的重要環節。其偽代碼如下：pp2=163–164

**選擇與排名**
若在節點中維護以之為根節點的子樹的節點總數，則可實現選擇與排名操作。選擇操作用於在樹中直接定位排名為的節點，即第小的鍵。pp2=257–258排名操作則與之相對，給定指定鍵後，其會返回小於該鍵的節點數。pp2=258–259這兩種操作的偽代碼如下：pp2=258–259
其中size表示子樹規模信息，即子樹中節點數量。

**範圍查找**
利用中序遍歷，可以實現範圍查找，即查詢兩個給定值之間的元素數量。其偽代碼如下：pp2=261–262
其中list是用來收集結果的列表（也可視作隊列）。上述過程將所有符合條件的值加入列表中，並跳過不可能含有目標值的子樹。

**插入**
二叉搜索樹的數據結構會隨插入和刪除操作而變化。插入操作須保證二叉搜索樹的性質不會遭到破壞，且插入的節點總是作為葉節點加入。pp2=165–166以下偽代碼給出迭代形式的插入過程：pp2=165–166
過程使用變量作為遍歷節點的父節點（追蹤指針）。初始時如果為，說明樹為空，新節點即作為樹的根；否則，需根據節點鍵值大小關係插入對應位置。p2=166

**刪除**
二元搜尋樹刪除節點的過程
從樹中刪除某個節點時，需分三種情況處理：pp2=166-167
# 是葉節點：直接用空指針替換即可。（如圖中(a)）
# 僅有一個子節點：用的子節點替換。（如圖中(b)、(c)）
# 有兩個子節點：用的中序遍歷所得到的後繼或前驅代替。此處以後繼為例：
## 如果恰好是的右子節點：直接用取代，的右子樹保持不變。（如圖中(d)）
## 如果位於的右子樹內部：先用的右子節點替換，再用替代。（如圖中(e)）
以下偽代碼實現刪除操作：p2=167-168
過程根據上述3種情況處理節點刪除：第1種情況（葉節點）對應第2—3行；第2種情況（單個子節點）對應第4—5行；第3種情況（有兩個子節點）對應第6—16行。輔助函數用於把節點替換成。pp2=167-168
若在第3種情況中，僅選用後繼或前驅節點中的一種，則並未考慮到樹的對稱性，可能會導致性能問題。若要避免此問題，可以隨機選擇使用後繼或前驅。p2=260

**平衡樹**
普通的二叉搜索樹中，若不加以平衡，插入或刪除操作可能會導致樹退化。uci-01若是使用隨機鍵值構建二叉搜索樹，那麼平均高度仍能維持在對數級別（當節點數足夠大時，高度趨近於）；p2=263但在最壞情況下，高度會達到節點數，查找性能退化至線性搜索的-{zh:水平;zh-hans:水平;zh-hant:水平;zh-tw:水準;}-。uci-01要保持二叉搜索樹的高效，關鍵在於通過「自平衡」機制，使樹的高度始終維持在級別。p2=50

**高度平衡樹**
若一棵樹的任意節點，其左右子樹高度之比都被某個常數所限制，就稱其為高度平衡樹。這一思想最早在AVL樹中使用，後續的紅黑樹也沿用了類似機制。pp=50-51每次執行插入或刪除操作後，需要沿著從根到修改節點的路徑，檢查並修正各節點的高度，以維持平衡。p=52

**加權平衡樹**
在加權平衡樹中，平衡條件不再以高度衡量，而是以子樹的葉節點數量為準。葉節點數量即代表權重，左右子樹的權重差最多為常數。p=61但單純依靠差值，難以在插入和刪除時用的代價維護，因此引入比例因子，要求左右子樹的權重各自至少佔整棵子樹權重的比例，由此形成-權重平衡樹族。p=62

**其他類型**
常見的自平衡二叉搜索樹包括：T-tree、樹堆Aragon1989、紅黑樹p2=174、B樹Comer1979、2-3樹q=The 2–3 trees defined at the close of Section 6.2.3 are equivalent to B-Trees of order 3.、伸展樹Sleator1985。

**應用**

**排序**
二叉搜索樹可用於樹排序：先將所有元素插入二叉搜索樹中，然後對樹做中序遍歷，即可得到有序序列。princeton-01在快速排序的某些實現中，也可藉助二叉搜索樹來提高性能。emory-01

**優先隊列**
二叉搜索樹也可用來實現優先隊列，藉助節點的鍵值來表示優先級。插入操作與普通的二叉搜索樹相同，但刪除操作取決於優先隊列的類型：cornell-02- 升序優先隊列：移除最低優先級元素時，從根節點向左一路遍歷即可找到最小鍵。- 降序優先隊列：移除最高優先級元素時，從根節點向右一路遍歷即可找到最大鍵。

**參見**
 搜索樹- 最優二叉搜索樹- Geometry of binary search trees- 三叉搜索樹

**腳註**

**註釋**

**來源**

**延伸閱讀**
 binarySearchTree- Cite book |url=https://mitpress.mit.edu/books/introduction-algorithms-second-edition |title=Introduction to Algorithms |last=Cormen |first=Thomas H. |author-link=Thomas H. Cormen |last2=Leiserson |first2=Charles E. |author-link2=Charles E. Leiserson |last3=Rivest |first3=Ronald L. |author-link3=Ronald L. Rivest |last4=Stein |first4=Clifford |author-link4=Clifford Stein |publisher=MIT Press |year=2001 |isbn=0-262-03293-7 |edition=2nd |pages=253–272, 356–363 |language=en |chapter=12: Binary search trees, 15.5: Optimal binary search trees- Cite web |title=Binary Tree Traversals |url=http://nova.umuc.edu/~jarc/idsv/lesson1.html |website=Interactive Data Structure Visualizations |date=2005-12-03 |language=en |last=Jarc |first=Duane J. |url-status=dead |archive-url=https://web.archive.org/web/20140227082917/http://nova.umuc.edu/~jarc/idsv/lesson1.html |archive-date=2014-02-27 |access-date=2006-04-30 |publisher=University of Maryland- Cite book |title=The Art of Computer Programming |last=Knuth |first=Donald |author-link=Donald Knuth |publisher=Addison-Wesley |year=1997 |isbn=0-201-89685-0 |edition=3rd |volume=3: "Sorting and Searching" |pages=426–458 |language=en |chapter=6.2.2: Binary Tree Searching- Cite web |title=Binary Trees |url=http://cslibrary.stanford.edu/110/BinaryTrees.html |website=CS Education Library |language=en |last=Parlante |first=Nick |year=2001 |url-status=live |archive-url=https://ghostarchive.org/archive/20220130/http://cslibrary.stanford.edu/110/BinaryTrees.html |archive-date=2022-01-30 |publisher=Stanford University

**外部鏈接**
 Harsha Suryanarayana的教學視頻：language=en- Ben Pfaff:  An Introduction to Binary Search Trees and Balanced Trees. (PDF; 1675 kB) 2004. en-  二叉搜索樹的可視化頁面zh-cn，支持動畫顯示二叉搜索樹的插入、查找、刪除操作。