參考:
微信
知乎
此三者的主要應用是降低大數據量檢索時的時間複雜度。
- JAVA的hashMap中,當一個桶中的元素個數超過…時,桶內數據的存儲結構會由鏈表改成紅黑樹。
- MySql數據庫中,對於數據量超大的數據進行索引時,會採用B+樹的存儲結構。(索引數據結構的演變:紅黑樹->B樹->B+樹)
二叉查找樹
對二叉樹做中根遍歷,數據是有序的,也稱二叉排序樹、二叉搜索樹。
- 每個節點最多有兩個子節點
- 節點的左子樹中所有節點的值都小於這個節點的值,節點的右子樹中所有節點的值都大於這個節點的值
平衡二叉樹
每個節點的左右兩個子樹的高度差不大於1的二叉搜索樹。
紅黑樹
紅黑樹是一種自平衡二叉查找樹,又稱爲"對稱二叉B樹",它的統計性能要好於平衡二叉樹。其典型的用途是實現關聯數組。
特性
- 每個節點都帶有顏色屬性
- 根節點黑色、葉節點黑色、葉子節點必須是NULL
- 紅色節點的兩個子節點都是黑色
- 從任一節點到其每個葉子節點的所有路徑都包含相同數目的黑色節點
自平衡
通過右旋、左旋、變色來實現。
- 左旋:假設以節點P爲軸做左旋操作,那麼其右子節點R變更爲根節點,其自身變更爲R的左子節點,R原來的左子節點變更爲P的右子節點
- 右旋:對節點P做右旋操作,則P的左子節點L變更爲根節點,P變更爲L的右子樹,L原來的右子樹變更爲P的左子樹。
- 變色:節點變顏色
插入新的節點時,自平衡規則
首先,插入的節點的顏色初值設爲紅色。 - 無需調整的情況:當插入位置的父節點爲黑色時
- 變色即可實現平衡:父節點和叔父節點(父節點的兄弟節點,不分左右)都爲紅色時,只需將插入的節點顏色變爲黑色即可。空樹插入時,插入的節點爲根,只需將節點顏色變爲黑色即可。
- 旋轉+變色:都是在父紅、叔父黑色情況下,
- 父節點爲左子節點,插入節點爲左子節點,即【左左】插入,需要祖父節點右旋+變色
- 父節點爲左子節點,插入節點爲右子節點,即【左右】插入,需要父節點左旋+祖父節點右旋+變色
- 父節點爲右子節點,插入節點爲左子節點,即【右左】插入,需要父節點右旋+祖父節點左旋+變色
- 父節點爲右子節點,插入節點爲右子節點,即【右右】插入,需要祖父節點左旋+變色
刪除節點
- 待刪除節點的左右子節點都爲 null,刪除時直接將該節點置爲 null。
- 待刪除節點的左右子節點有一個有值,則用有值的節點替換該節點即可。
- 待刪除節點的左右子節點都不爲 null,則找前驅或者後繼,將前驅或者後繼的值複製到該節點中,然後刪除前驅或者後繼
- 節點刪除後可能會造成紅黑樹的不平衡,這時我們需通過【變色】+【旋轉】的方式來調整,使之平衡。
B樹
紅黑樹是二叉樹,當數據量大時,其高度必然增大。且每次插入或者刪除都需要做平衡操作,很是消耗時間。
B樹,也是自平衡的排序查找樹,但是不要求子節點數目必須小於2。
- 每個節點可以有最多M個子節點,M>=2,M即爲B樹的階數
- 每個節點中可以存儲最多M個、最少M/2向上取整個key,一般爲2-3個。
- 所有葉子節點均在同一層
B樹的構建
B樹的構建過程中每個節點中的關鍵字的個數都在動態改變。
因爲其構建過程是:對節點先擴充,當節點中關鍵字數量擴充到等於M時,再對其進行拆分,並將中間數升爲父節點。
例如:定義一個5階樹(平衡5路查找樹;),現在我們要把3、8、31、11、23、29、50、28 這些數字構建出一個5階樹出來;
遵循規則:
(1)節點拆分規則:當前是要組成一個5路查找樹,那麼此時m=5,關鍵字數必須<=5-1(這裏關鍵字數>4就要進行節點拆分);
(2)排序規則:滿足節點本身比左邊節點大,比右邊節點小的排序規則;
先插入 3、8、31、11
再插入23、29
再插入50、28
刪除節點
規則:
(1)節點合併規則:當前是要組成一個5路查找樹,那麼此時m=5,關鍵字數必須大於等於ceil(5/2)(這裏關鍵字數<2就要進行節點合併);
(2)滿足節點本身比左邊節點大,比右邊節點小的排序規則;
(3)關鍵字數小於二時先從子節點取,子節點沒有符合條件時就向向父節點取,取中間值往父節點放;
B+樹
B+樹是B樹的升級優化版,
- 非葉子節點中的關鍵字不指向實際對象,也就是說B+樹的非葉子節點不作存儲作用,僅用作檢索時的索引。
- 葉子節點保存了所有父節點的關鍵字指向的對象,所有數據地址必須到葉子節點才能獲取到,因此所有數據的比較次數都一樣
- 葉子節點中的所有關鍵字從小到大有序排列,每個節點的最後一個關鍵字記錄了其右邊的節點的第一個關鍵字的指針
- 非葉子節點的關鍵字數=子節點數