二叉查找樹
二叉查找樹,也稱有序二叉樹(ordered binary tree),或已排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
任意節點的左、右子樹也分別為二叉查找樹。
沒有鍵值相等的節點(no duplicate nodes)。
因為一棵由n個結點隨機構造的二叉查找樹的高度為lgn,所以順理成章,二叉查找樹的一般操作的執行時間為O(lgn)。但二叉查找樹若退化成了一棵具有n個結點的線性鏈后,則這些操作最壞情況運行時間為O(n)。
avl樹即平衡樹,他對二叉樹做了改進,在我們每插入一個節點的時候,必須保證每個節點對應的左子樹和右子樹的樹高度差不超過1。如果超過了就對其進行調平衡,具體的調平衡操作就不在這里講了,無非就是四個操作——左旋,左旋再右旋,右旋再左旋。
如圖所示,圖中M結點就是一個二節點,M左邊的EJ節點是一個三節點。依然是大的數據放右邊,小的數據放左邊。此時我們向該樹重如果該數可以直接放入二節點中,就直接進去,但如果正好需要放在三節點中,就像圖中一樣,Z正好要放在SX中。那么我們需要將該節點分裂成兩個節點,並將中間的數提到父節點中去,就像圖中將X放在了R旁邊。當然如果將子節點提到父節點的時候導致了父節點里的數超過了兩個,就繼續向上提,直到滿足了為止。
在jdk1.8版本后,java對HashMap做了改進,在鏈表長度大於8的時候,將后面的數據存在紅黑樹中,以加快檢索速度,我們接下來講一下紅黑樹。
紅黑樹雖然本質上是一棵二叉查找樹,但它在二叉查找樹的基礎上增加了着色和相關的性質使得紅黑樹相對平衡,從而保證了紅黑樹的查找、插入、刪除的時間復雜度最壞為O(log n)。加快檢索速率。
紅黑樹的5個性質:
1.每個結點要么是紅的要么是黑的。
2.根結點是黑的。
3.每個葉結點(葉結點即指樹尾端NIL指針或NULL結點)都是黑的。
4.如果一個結點是紅的,那么它的兩個兒子都是黑的。
5. 對於任意結點而言,其到葉結點樹尾端NIL指針的每條路徑都包含相同數目的黑結點。
紅黑樹還可以描述成:
⑴紅鏈接均為左鏈接。
⑵沒有任何一個結點同時和兩條紅鏈接相連。
⑶該樹是完美黑色平衡的,即任意空鏈接到根結點的路徑上的黑鏈接數量相同。
這里節點之間的連接分為紅連接和黑連接,取代了紅節點和黑節點的定義(本質是一樣的),將之前的黑高度相等定義為了黑連接數相等。更為直觀。
而如圖所示,其實紅黑樹的每一步操作都對應了二三樹的操作,如果是二節點就是黑連接,三節點的話里面的兩個數之間就是紅連接。
紅黑樹相比avl樹,在檢索的時候效率其實差不多,都是通過平衡來二分查找。但對於插入刪除等操作效率提高很多。紅黑樹不像avl樹一樣追求絕對的平衡,他允許局部很少的不完全平衡,這樣對於效率影響不大,但省去了很多沒有必要的調平衡操作,avl樹調平衡有時候代價較大,所以效率不如紅黑樹。