紅黑樹和AVL樹有什麼區別?
紅黑樹 vs AVL
紅黑樹的查詢性能略微遜色於AVL樹,因爲他比avl樹會稍微不平衡最多一層,也就是說紅黑樹的查詢性能只比相同內容的avl樹最多多一次比較,但是,紅黑樹在插入和刪除上完爆avl樹,avl樹每次插入刪除會進行大量的平衡度計算,而紅黑樹爲了維持紅黑性質所做的紅黑變換和旋轉的開銷,相較於avl樹爲了維持平衡的開銷要小得多
平衡二叉樹的性質:
1、AVL樹是自平衡二分搜索樹
2、平衡二叉樹
(1)對於任意一個節點,左子樹和右子樹的高度差不能超過爲1。
(2)對於堆和線段二叉樹來說,可以保證任意一個葉子節點相應的高度差不能超過1。
AVL樹查找、插入和刪除在平均和最壞情況下都是O(log n)。
下圖爲平衡二叉樹
下圖爲不平衡二叉樹
3、平衡因子
跟蹤每個節點,對應的高度,這樣才能判斷是否平衡
標註節點的高度差,左子樹減去右子樹
“2”節點高度差爲 0-0=0 ,左子樹高度爲0,右子樹高度爲0
“8”節點高度差爲 3-1=2,左子樹高度爲3,右子樹高度爲1
“12”節點高度差爲4-2= 2,左子樹高度爲4,右子樹高度爲2
4、什麼時候維護平衡
在二分搜索樹中要插入一個節點,需要從根節點一路下來,最終尋找到這個節點的插入位置,插入節點的位置都是葉子節點的位置。
28下來到33的左子樹
由於新添加一個節點,纔有可能導致二分搜索樹不在滿足平衡性,相應的不平衡節點,只有可能發送在插入的位置,向父親節點去找,
因爲插入新節點破壞了平衡性,高度就要更新,平衡因子就會大於1或者小於-1.
5、右旋轉
左子樹的高度比右子樹的高度要高,高度差比1大
(1)首先將 x 的右子樹變成以y節點根的子樹,T3放一邊,x.right =y
(2)在讓y節點的左子樹變成剛剛x的右子樹所連接的T3,y.left=T3
(3)這裏讓x變成這個平衡二叉樹的根節點。
左旋一樣的道理
6、適用性:AVL查找效率高
如果你的應用中,搜索的次數遠遠大於插入和刪除,那麼選擇AVL樹,
應用:Windows NT內核中廣泛存在
紅黑樹的性質:
-
節點是紅色或黑色。
-
根節點是黑色。
如果根節點是2節點,就是黑色的節點
如果根節點是3節點,根節是c節點,依然是黑色節點
-
每一個葉子節點(最後的空節點)是黑色。
相當於紅黑樹定義空這樣的節點本身就是黑色的
極端情況下,整棵樹都空,這個空即是葉子節點又是黑色,定義他是黑色的。 -
如果一個節點是紅色的,那麼他的孩子節點都是黑色的
-
從任意一個節點到葉子節點,經過的黑色節點是一樣的
2、紅黑樹是保持“黑平衡”的二叉樹。
對於黑平衡是指,從根節點開始搜索,一直搜索到葉子節點,所經歷的黑色節點的個數是一樣的。、
黑平衡二叉樹,嚴格意義上,不是平衡二叉樹。
左右子樹的高度差可能大於1。
時間複雜度是O(logn),最大高度:2logn
紅黑樹不會像二分搜索樹一樣退化爲鏈表。
查找的時間上面會比AVL樹慢一點,因爲最大高度爲2logn
添加操作和刪除操作比AVL樹要快一些
下面是添加一個元素
(1)如果三節點中間添加一個元素,先左旋轉——》右旋轉——》顏色翻轉
(2)如果三節點添加比這兩個元素還要小的元素,直接跳到——》右旋轉——》顏色翻轉
(3)如果三節點添加比這兩個元素都要大的元素,直接跳到——》顏色翻轉
3、維護的時間和AVL樹一樣:
都使用二分搜索樹基本邏輯,新的節點添加進紅黑樹中,之後再進行紅黑樹性質維護,在維護完將根節點返回到遞歸,調用上層,從上一層角度再看是否還需要維護新的節點,以此類推。
紅黑樹性能總結
1、對於完全隨機的數據,普通的二分搜索樹很好用。
缺點:極端情況退化成鏈表(或者高度不平衡)
2、對於查詢較多的使用情況,AVL樹很好用。
紅黑樹犧牲平衡性(2logn高度)。
紅黑樹統計性能更優(綜合增刪改查所有操作)
有序底層TreeSet、TreeMap都是紅黑樹
應用
1、着名的Linux的的進程調度完全公平調度程序,用紅黑樹管理進程控制塊,進程的虛擬內存區域都存儲在一顆紅黑樹上,每個虛擬地址區域都對應紅黑樹的一個節點,左指針指向相鄰的地址虛擬存儲區域,右指針指向相鄰的高地址虛擬地址空間;
2、IO多路複用的epoll的的的實現採用紅黑樹組織管理的的的sockfd,以支持快速的增刪改查;
3、Nginx的的的中用紅黑樹管理定時器,因爲紅黑樹是有序的,可以很快的得到距離當前最小的定時器;
4、Java的的的中TreeMap中的中的實現;