平衡二叉搜索樹
平衡二叉搜索樹(英語:Balanced Binary Search Tree)是一種結構平衡的[二叉搜索樹] ,它是一種每個節點的左右兩子[樹] 高度差都不超過一的[二叉樹] 。它能在O(logn)
內完成插入、查找和刪除操作,最早被發明的平衡二叉搜索樹為[AVL樹] 。
之前的BST已經可以解決很多查找問題,而且時間復雜度在O(logN)
,但是如果出現單支樹的情況,時間復雜度就會退化到O(N)
,也就是類似於單鏈表的查詢。
AVL樹
AVL樹是最早被發明的自平衡二叉查找樹。在AVL樹中,任一節點對應的兩棵子樹的最大高度差為1,因此它也被稱為高度平衡樹。查找、插入和刪除在平均和最壞情況下的時間復雜度都是O(logn)
。增加和刪除元素的操作則可能需要借由一次或多次樹旋轉,以實現樹的重新平衡。
平衡因子
它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過1。若將二叉樹上結點的平衡因子BF(Balance Factor)定義為LH-RH,那么BF只能是-1,0,1。只要|BF|>=1,則二叉樹就是不平衡的。
平衡二叉樹
不平衡的二叉樹
旋轉
OK,現在我們一眼可以看出哪種是平衡,哪種是不平衡的。如果不平衡的二叉樹,就需要做旋轉
哪些操作會導致原來平衡的二叉樹,變得不平衡?插入一個新的節點,或者刪除一個節點,都有可能導致二叉樹的平衡結構被破壞。此時就會需要通過自身旋轉,來修復。
假設平衡因子是左子樹的高度減去右子樹的高度所得到的值,又假設由於在二叉排序樹上插入節點而失去平衡的最小子樹根節點的指針為a(即a是離插入點最近,且平衡因子絕對值超過1的祖先節點),則失去平衡后進行的規律可歸納為下列四種情況:
-
單向右旋平衡處理LL:由於在a的左子樹根節點的左子樹上插入節點,a的平衡因子由1增至2,致使以*a為根的子樹失去平衡,則需進行一次右旋轉操作;
-
單向左旋平衡處理RR:由於在a的右子樹根節點的右子樹上插入節點,a的平衡因子由-1變為-2,致使以*a為根的子樹失去平衡,則需進行一次左旋轉操作;
-
雙向旋轉(先左后右)平衡處理LR:由於在a的左子樹根節點的右子樹上插入節點,a的平衡因子由1增至2,致使以*a為根的子樹失去平衡,則需進行兩次旋轉(先左旋后右旋)操作。
-
雙向旋轉(先右后左)平衡處理RL:由於在a的右子樹根節點的左子樹上插入節點,a的平衡因子由-1變為-2,致使以*a為根的子樹失去平衡,則需進行兩次旋轉(先右旋后左旋)操作。
BBST插入e 遞歸算法
在平衡的二叉排序樹BBST (Balancing Binary Search Tree)上插入一個新的數據元素e的遞歸算法可描述如下:
- 若BBST為空樹,則插入一個數據元素為e的新節點作為BBST的根節點,樹的深度增1;
- 若e的關鍵字和BBST的根節點的關鍵字相等,則不進行;
- 若e的關鍵字小於BBST的根節點的關鍵字,而且在BBST的左子樹中不存在和e有相同關鍵字的節點,則將e插入在BBST的左子樹上,並且當插入之后的左子樹深度增加(+1)時,分別就下列不同情況處理之:
- BBST的根節點的平衡因子為-1(右子樹的深度大於左子樹的深度,則將根節點的平衡因子更改為0,BBST的深度不變;
- BBST的根節點的平衡因子為0(左、右子樹的深度相等):則將根節點的平衡因子更改為1,BBST的深度增1;
- BBST的根節點的平衡因子為1(左子樹的深度大於右子樹的深度):則若BBST的左子樹根節點的平衡因子為1:則需進行單向右旋平衡處理,並且在右旋處理之后,將根節點和其右子樹根節點的平衡因子更改為0,樹的深度不變;
- 若e的關鍵字大於BBST的根節點的關鍵字,而且在BBST的右子樹中不存在和e有相同關鍵字的節點,則將e插入在BBST的右子樹上,並且當插入之后的右子樹深度增加(+1)時,分別就不同情況處理之。
本文是作者閑來無事,寫的水文,如果想要獲得更詳細的請參考WIKI和數據結構相關書籍。