紅黑樹(red-black tree)是一種改進的二叉查找樹,結點域中增長顏色屬性(紅或黑)。
二叉查找樹的通常操做的時間爲 O(lgn)。但若它退化成一棵n個結點的線性鏈後,操做最壞時間爲
O(n)。而紅黑樹增長了着色和相關性質保證了查找、插入、刪除的時間複雜度最壞爲 O(lgn).java
特徵算法
紅黑樹和234樹是一種等價的數據結構數據結構
紅黑樹上的search、minimum、maximum、successor、predecessor 能夠在 O(logn)內完成。
時間複雜度O(1)
性能
left-rotate(T,x) y=right[x] right[x]=left[x] p[left[y]]=x p[y]=p[x] if p[x]=nil root[T]=y else if x=left[p[x]] left[p[x]]Åy else right[p[x]]=y left[y]=x p[x]=y
jdk8 TreeMap右旋源代碼ui
/** From CLR */ private void rotateRight(Entry<K,V> p) { if (p != null) { Entry<K,V> l = p.left; p.left = l.right; if (l.right != null) l.right.parent = p; l.parent = p.parent; if (p.parent == null) root = l; else if (p.parent.right == p) p.parent.right = l; else p.parent.left = l; l.right = p; p.parent = l; } }
主要分兩步:.net
二叉查找樹的就是一個二分查找,找到合適的位置就放進去。紅黑樹的插入在二叉查找樹插入的基礎上,爲了從新恢復平衡,繼續作了插入修復操做。設計
當咱們往紅黑樹中插入一個黑色節點時,會打破一個平衡:任一節點到它子樹的每一個葉子節點的路徑中都包含一樣數量的黑節點。
當咱們給一個紅色節點下插入一個紅色節點時,會打破另外一個平衡:紅色節點的左右孩子必定都是黑色節點。
爲了簡化調整,咱們直接把插入的節點直接染成紅色,這樣就不會影響上一個平衡,只要專心調整知足後一個平衡就行了。染成紅色後,咱們只要關心父節點是否爲紅,若是是紅的,就要把父節點進行變化,讓父節點變成黑色,或者換一個黑色節點當父親,這些操做的同時不能影響 不一樣路徑上的黑色節點數一致的規則。指針
關注插入節點的父親節點的位置,而父親節點位於其爺爺節點地左子樹或者右子樹的操做是相對稱的,座椅只須要研究一側,即插入位置的父親節點爲左子樹。code
插入、染紅後的調整有 2 種狀況:blog
狀況1.父親節點和叔叔節點都是紅色
如上圖所示,假設插入的是節點 N,這時父親節點 P 和叔叔節點 U 都是紅色,爺爺節點 G 必定是黑色。
紅色節點的孩子不能是紅色,這時無論 N 是 P 的左孩子仍是右孩子,只要同時把 P 和 U 染成黑色,G 染成紅色便可。這樣這個子樹左右兩邊黑色個數一致,也知足特徵 4。
可是這樣改變後 G 染成紅色,G 的父親若是是紅色可能又違反特徵 4 了,所以須要以 爺爺節點 G 爲新的調整節點,再次進行循環調整操做,直到父親節點不是紅的。
狀況2.父親節點爲紅色,叔叔節點爲黑色
如上圖所示,假設插入的是節點 N,這時父親節點 P 是紅色,叔叔節點 U 是黑色,爺爺節點 G 必定是黑色。
紅色節點的孩子不能是紅色,可是直接把父親節點 P 塗成黑色也不行,這條路徑多了個黑色節點。
經過把 爺爺節點 G 右旋,P 變成了這個子樹的根節點,G 變成了 P 的右子樹。
右旋後 G 跑到了右子樹上,這時把 P 變成黑的,多了一個黑節點,再把 G 變成紅的,就平衡了!
上面講的是插入節點 N 在父親節點 P 的左孩子位置,若是 N 是 P 的右孩子,就須要多進行一次左旋,把狀況化解成上述狀況,以下圖:
時間複雜度:O(lgn),最多兩次旋轉
4. 刪除
O(lgn)最多三次旋轉
5. 查找
O(lgn)
序統計樹
序統計就是在一系列數中找出最大、最小值,某個數的序值等操做。
結點域增長size(以x爲根的子樹所包含的內部結點數,包括x)
操做的時間複雜度O(lgn)
區間樹O(lgn)
《算法導論》
https://blog.csdn.net/lanchunhui/article/details/75905478
https://blog.csdn.net/u011240877/article/details/53329023
http://www.javashuo.com/article/p-vrluzavz-ez.html