1. 程式人生 > >紅黑樹和AVL平衡樹的區別

紅黑樹和AVL平衡樹的區別

1 排序二叉樹

排序二叉樹是一種特殊結構的二叉樹,可以非常方便地對樹中所有節點進行排序檢索。 排序二叉樹要麼是一棵空二叉樹,要麼是具有下列性質的二叉樹: • 若它的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值; • 若它的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值; • 它的左、右子樹也分別為排序二叉樹。 下圖顯示了一棵排序二叉樹:

對排序二叉樹,若按中序遍歷就可以得到由小到大的有序序列。中序遍歷得: {2,3,4,8,9,9,10,13,15,18} 排序二叉樹雖然可以快速檢索,但在最壞的情況下:如果插入的節點集本身就是有序的,要麼是由小到大排列,要麼是由大到小排列,那麼最後得到的排序二叉樹將變成連結串列

:所有節點只有左節點(如果插入節點集本身是大到小排列);或所有節點只有右節點(如果插入節點集本身是小到大排列)。在這種情況下,排序二叉樹就變成了普通連結串列,其檢索效率就會很差

2 紅黑樹

《演算法導論》關於紅黑樹的定義:

正如在CLRS中定義的那樣(CLRS指的是就是演算法導論這本書《Introduction to Algorithms》,CLRS是該書作者Cormen, Leiserson, Rivest and Stein的首字母縮寫),一棵紅黑樹是指一棵滿足下述性質的二叉搜尋樹(BST, binary search tree): 1. 每個結點或者為黑色或者為紅色。 2. 根結點為黑色。 3. 每個葉結點(實際上就是NULL指標)都是黑色的。 4. 如果一個結點是紅色的,那麼它的兩個子節點都是黑色的(也就是說,不能有兩個相鄰的紅色結點)。 5. 對於每個結點,從該結點到其所有子孫葉結點的路徑中所包含的黑色結點數量必須相同。

資料項只能儲存在內部結點中(internal node)。我們所指的"葉結點"在其父結點中可能僅僅用一個NULL指標表示,但是將它也看作一個實際的結點有助於描述紅黑樹的插入與刪除演算法,葉結點一律為黑色。 定義詳解: 根據性質 5:紅黑樹從根節點到每個葉子節點的路徑都包含相同數量的黑色節點,因此從根節點到葉子節點的路徑中包含的黑色節點數被稱為樹的“黑色高度(black-height)”。 性質 4 則保證了從根節點到葉子節點的最長路徑的長度不會超過任何其他路徑的兩倍。假如有一棵黑色高度為 3 的紅黑樹:從根節點到葉節點的最短路徑長度是 2,該路徑上全是黑色節點(黑節點 – 黑節點 – 黑節點)。最長路徑也只可能為 4,在每個黑色節點之間插入一個紅色節點(黑節點 – 紅節點 – 黑節點 – 紅節點 – 黑節點),性質 4 保證絕不可能插入更多的紅色節點。由此可見,紅黑樹中最長路徑就是一條紅黑交替的路徑

。 根據定義我們做如下練習: -不符合定義的一顆非紅黑樹:  紅黑樹的這5個性質中,第3點是比較難理解的,但它卻非常有必要。我們看圖1中的左邊這張圖,如果不使用黑哨兵,它完全滿足紅黑樹性質,結點50到兩個葉結點8和葉結點82路徑上的黑色結點數都為2個。但如果加入黑哨兵後(如圖1右圖中的小黑圓點),葉結點的個數變為8個黑哨兵,根結點50到這8個葉結點路徑上的黑高度就不一樣了,所以它並不是一棵紅黑樹。 -兩顆正確的紅黑樹:  定理

一棵擁有n個內部結點的紅黑樹的樹高h<=2log(n+1)

由此我們可以得出結論:對於給定的黑色高度為 N 的紅黑樹,從根到葉子節點的最短路徑長度為 N-1,最長路徑長度為 2 * (N-1)。 提示:排序二叉樹的深度直接影響了檢索的效能,正如前面指出,當插入節點本身就是由小到大排列時,排序二叉樹將變成一個連結串列,這種排序二叉樹的檢索效能最低:N 個節點的二叉樹深度就是 N-1。 紅黑樹通過上面這種限制來保證它大致是平衡的——因為紅黑樹的高度不會無限增高,這樣保證紅黑樹在最壞情況下都是高效的,不會出現普通排序二叉樹的情況。 由於紅黑樹只是一個特殊的排序二叉樹,因此對紅黑樹上的只讀操作與普通排序二叉樹上的只讀操作完全相同,只是紅黑樹保持了大致平衡,因此檢索效能比排序二叉樹要好很多。 但在紅黑樹上進行插入操作和刪除操作會導致樹不再符合紅黑樹的特徵,因此插入操作和刪除操作都需要進行一定的維護,以保證插入節點、刪除節點後的樹依然是紅黑樹。 

3 紅黑樹和AVL樹的比較

1. 紅黑樹並不追求“完全平衡”——它只要求部分地達到平衡要求,降低了對旋轉的要求,從而提高了效能。 紅黑樹能夠以O(log2 n) 的時間複雜度進行搜尋、插入、刪除操作。此外,由於它的設計,任何不平衡都會在三次旋轉之內解決。當然,還有一些更好的,但實現起來更復雜的資料結構,能夠做到一步旋轉之內達到平衡,但紅黑樹能夠給我們一個比較“便宜”的解決方案。紅黑樹的演算法時間複雜度和AVL相同,但統計效能比AVL樹更高。 當然,紅黑樹並不適應所有應用樹的領域。如果資料基本上是靜態的,那麼讓他們待在他們能夠插入,並且不影響平衡的地方會具有更好的效能。如果資料完全是靜態的,做一個雜湊表,效能可能會更好一些。 紅黑樹是一個更高效的檢索二叉樹,因此常常用來實現關聯陣列。典型地,JDK 提供的集合類 TreeMap 本身就是一個紅黑樹的實現。 TreeMap 和 TreeSet 是 Java Collection Framework 的兩個重要成員,其中 TreeMap 是 Map 介面的常用實現類,而 TreeSet 是 Set 介面的常用實現類。雖然 HashMap 和 HashSet 實現的介面規範不同,但 TreeSet 底層是通過 TreeMap 來實現的,因此二者的實現方式完全一樣。而 TreeMap 的實現就是紅黑樹演算法。 對於 TreeMap 而言,由於它底層採用一棵“紅黑樹”來儲存集合中的 Entry,這意味這 TreeMap 新增元素、取出元素的效能都比 HashMap 低:當 TreeMap 新增元素時,需要通過迴圈找到新增 Entry 的插入位置,因此比較耗效能;當從 TreeMap 中取出元素時,需要通過迴圈才能找到合適的 Entry,也比較耗效能。 但 TreeMap、TreeSet 比 HashMap、HashSet 的優勢在於:TreeMap 中的所有 Entry 總是按 key 根據指定排序規則保持有序狀態,TreeSet 中所有元素總是根據指定排序規則保持有序狀態。 2 AVL樹是最先發明的自平衡二叉查詢樹。在AVL樹中任何節點的兩個兒子子樹的高度最大差別為一,所以它也被稱為高度平衡樹。查詢、插入和刪除在平均和最壞情況下都是O(log n)。增加和刪除可能需要通過一次或多次樹旋轉來重新平衡這個樹。 引入二叉樹的目的是為了提高二叉樹的搜尋的效率,減少樹的平均搜尋長度.為此,就必須每向二叉樹插入一個結點時調整樹的結構,使得二叉樹搜尋保持平衡,從而可能降低樹的高度,減少的平均樹的搜尋長度. AVL樹的定義:
一棵AVL樹滿足以下的條件: 1>它的左子樹和右子樹都是AVL樹 2>左子樹和右子樹的高度差不能超過1
性質:
1>一棵n個結點的AVL樹的其高度保持在0(log2(n)),不會超過3/2log2(n+1) 2>一棵n個結點的AVL樹的平均搜尋長度保持在0(log2(n)). 3>一棵n個結點的AVL樹刪除一個結點做平衡化旋轉所需要的時間為0(log2(n)).
為了保證平衡,AVL樹中的每個結點都有一個平衡因子(balance factor,以下用BF表示),它表示這個結點的左、右子樹的高度差,也就是左子樹的高度減去右子樹的高度的結果值。AVL樹上所有結點的BF值只能是-1、0、1。反之,只要二叉樹上一個結點的BF的絕對值大於1,則該二叉樹就不是平衡二叉樹。下圖演示了平衡二叉樹和非平衡二叉樹。 從1這點來看紅黑樹是犧牲了嚴格的高度平衡的優越條件為代價紅黑樹能夠以O(log2 n)的時間複雜度進行搜尋、插入、刪除操作。此外,由於它的設計,任何不平衡都會在三次旋轉之內解決。當然,還有一些更好的,但實現起來更復雜的資料結構能夠做到一步旋轉之內達到平衡,但紅黑樹能夠給我們一個比較“便宜”的解決方案。紅黑樹的演算法時間複雜度和AVL相同,但統計效能比AVL樹更高

相關推薦

AVL平衡區別

1 排序二叉樹 排序二叉樹是一種特殊結構的二叉樹,可以非常方便地對樹中所有節點進行排序和檢索。 排序二叉樹要麼是一棵空二叉樹,要麼是具有下列性質的二叉樹: • 若它的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值; • 若它的右子樹不空,則右子樹上所有節點的值

資料結構中常見的(BST二叉搜尋AVL平衡二叉、RBT、B-、B+、B*

BST樹 即二叉搜尋樹:        1.所有非葉子結點至多擁有兩個兒子(Left和Right);        2.所有結點儲存一個關鍵字;        3.非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹; 如:      

關於AVL,以下哪種說法不正確?----騰訊2016研發工程師線上模擬筆試題

關於紅黑樹和AVL樹,以下哪種說法不正確? 正確答案: D   你的答案: 空 (錯誤) 兩者都屬於自平衡二叉樹 兩者查詢,插入,刪除的時間複雜度相同 包含n個內部節點的紅黑樹的高度是O(log(n)) JDK的TreeMap是一個AVL的實現

AVL的效率對比

為什麼選擇紅黑樹作為底層實現 紅黑樹是一種類平衡樹, 但它不是高度的平衡樹, 但平衡的效果已經很好了. 補充說明另一種 AVL 樹, 我之前的博文: 《程式設計珠璣,字字珠璣》讀書筆記完結篇——AVL樹 用過 STL map 麼, 你用過 linux 麼(這

平衡二叉AVL

1  概述               對於一棵二分搜尋樹,如果我們的資料是順序新增到二分搜尋樹中,它就會退化成一個連結串列。我們如何解決這個問題呢,我們需要在現有的二分搜尋樹的基礎上新增一些機制,使得我們二分搜尋樹能維持平衡二叉樹這樣的一個性質,而AVL就是一種最為經典的

AVL(自平衡)——c++實現

html pub private 檢查 具體實現 htm lose show data- AVL樹是高度平衡的而二叉樹。它的特點是:AVL樹中任何節點的兩個子樹的高度最大差別為1。 AVL樹本質上還是一棵二叉搜索樹,它的特點是: 1.本身首先是一棵二叉

資料結構學習-AVL平衡

環境:C++ 11 + win10 IDE:Clion 2018.3 AVL平衡樹是在BST二叉查詢樹的基礎上添加了平衡機制。 我們把平衡的BST認為是任一節點的左子樹和右子樹的高度差為-1,0,1中的一種情況,即不存在相差兩層及以上。 所謂平衡機制就是BST在理想情況下搜尋複雜度是o(logn)

AVL平衡插入刪除結點過程平衡操作圖示

AVL插入結點 通過這張圖來描述AVL平衡樹在插入新結點過程中,通過旋轉操作來達到自平衡的四種場景: LL單旋轉:新結點插入在A的左孩子(L)的左子樹(L),這種場景在插入新結點後,同一路徑上的A和B的平衡因子符號相同(2,1),只需要一次右旋操作即可重新達到平衡。 LR雙旋

CART迴歸CART分類區別

除了概念的不同,CART迴歸樹和CART分類樹的建立和預測的區別主要有下面兩點:1)連續值的處理方法不同2)決策樹建立後做預測的方式不同。對於連續值的處理,CART分類樹採用的是用基尼係數的大小來度量特徵的各個劃分點的優

資料結構----AVL平衡----AVL平衡的基本操作

一、二叉查詢樹 我們先來講講二叉查詢樹。 大家應該聽說過二分查詢吧,二分查詢是對一個有序序列的快速查詢,時間複雜度為O(log2(n)), 但是二分查詢也有它的缺點,當序列加入一個元素時,我們就需要對這個有序序列進行維護,要麼就用sort(),要麼就用插入排序(附帶大量的資

二叉搜尋AVL平衡二叉搜尋

二叉搜尋樹 二叉搜尋樹是二叉樹的的一種,只不過多了個限制條件,即左子樹節點的值都小於該點,右子樹節點的值都大於該點。 定義: // 樹節點 template <typename T> class Node { public: T key; Nod

AVL平衡(二叉搜尋 c++實現)

                平衡查詢樹 程式碼: 指標實現 /*仿一個部落格的AVL*/ #include<iostream> #include<cstdlib> #include<cstdio> #include<al

AVL平衡裸題(營業額統計)

#include<iostream> #include<cstdio> #include<algorithm> #include<climits> const int MAXN=100000; using namespace std; st

資料結構之 AVL平衡 (c++)

一 AVL樹是一種高度平衡的二叉查詢樹,這裡將會簡單的提一下其演算法思想,不會討論複雜度的計算.只是想告訴大家,AVL樹的實現,及其平衡的過程. 二  平衡的演算法思想其實非常簡單, 就是將不平衡的二叉樹, 通過旋轉使其平衡. 下面舉個簡單的列子,大家就會明白了.    

AVL(二叉平衡)詳解與實現

AVL樹概念 前面學習二叉查詢樹和二叉樹的各種遍歷,但是其查詢效率不穩定(斜樹),而二叉平衡樹的用途更多。查詢相比穩定很多。(歡迎關注資料結構專欄) AVL樹是帶有平衡條件的二叉查詢樹。這個平衡條件必須要容易保持。而且要保證它的深度是O(logN). AVL的條件是左右樹的高度差(平衡因子)不大於1;並且它

二叉

reat 完成 child names space -1 include ges 中序 編程語言:c++ 截圖展示: 代碼如下: main.cpp 1 #include <iostream> 2 #include <cstdio&g

第六章 二叉

a20 cfb 樹和二叉樹 fff itblog ffd ace cab dac 第六章 樹和二叉樹

二叉->最優二叉

nco 代碼實現 type except close 輸出結點 eof fde 左右 文字描述 結點的路徑長度   從樹中一個結點到另一個結點之間的分支構成這兩個結點之間的路徑,路徑上的分支數目稱作路徑長度。 樹的路徑長度    從樹根到每一個結點的路徑長度之和叫樹的路徑長

數據結構——第三章二叉:01二叉的類型定義

有序 存在 lin 深度 操作 root 判定樹 delet eem 1.樹的類型定義: (1)數據對象D:D是具有相同特性的數據元素的集合。 (2)數據關系R:若D為空集,則成為空樹 否則:在D中存在唯一的稱為根的數據元素root。當n>1時,其余結點可分為n(n&

資料結構——第三章二叉:02二叉

1.二叉樹的儲存結構: (1)二叉樹的順序儲存表示: #define MAX_TREE_SIZE 100 //二叉樹的最大結點數 typedef TElemType SqBiTree[MAX_TREE_SIZE];  SqBiTree bt; (2)二叉樹的鏈式儲存表示: ①二叉連結