紅黑樹在Java中的應用
在Java中很多物件都使用了紅黑樹的資料結構,比如TreeMap,HashMap(1.8)等。然後我就想看看為什麼要使用這種資料結構?
要想了解紅黑樹,就先看看二叉查詢樹是什麼?
二叉查詢樹
二叉查詢樹(Binary Search Tree),也稱有序二叉樹(ordered binary tree),排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
- 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
- 若任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
- 任意節點的左、右子樹也分別為二叉查詢樹;
- 沒有鍵值相等的節點。
二叉查詢樹相比於其他資料結構的優勢在於查詢、插入的時間複雜度較低。為O(log n).
紅黑樹
二叉樹若退化成了一棵具有n個結點的線性鏈後,則此些操作最壞情況執行時間為O(n)。
後來就出現了紅黑樹的結構,來使樹相對平衡,最終插入,查詢、刪除的時間複雜複雜度最壞的情況是O(log n)
紅黑樹(),本質上來說就是一棵二叉查詢樹,但它在二叉查詢樹的基礎上增加了著色和相關的性質使得紅黑樹相對平衡,從而保證了紅黑樹的查詢、插入、刪除的時間複雜度最壞為O(log n)。
下面是紅黑樹的定義:https://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91#/media/File:Red-black_tree_example.svg
- 節點是紅色或黑色。
- 根是黑色。
- 所有葉子都是黑色(葉子是NIL節點)。
- 每個紅色節點必須有兩個黑色的子節點。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點。)
- 從任一節點到其每個葉子的所有簡單路徑都包含相同數目的黑色節點。
因為每一個紅黑樹也是一個特化的二叉查詢樹,因此紅黑樹上的只讀操作與普通二叉查詢樹上的只讀操作相同。
然而,在紅黑樹上進行插入操作和刪除操作會導致不再符合紅黑樹的性質。恢復紅黑樹的性質需要少量O(log n)的顏色變更(實際是非常快速的)和不超過三次樹旋轉(對於插入操作是兩次)。雖然插入和刪除很複雜,但操作時間仍可以保持為O(log n)次。
總結
紅黑樹相比二叉查詢樹在時間複雜度上要提升不少,所以JDK1.8中HashMap在單鏈表衝突後採用這種方式提高查詢插入的效率。
作者:狂奔的熊二