1. 程式人生 > >面試題——輕鬆搞定面試中的紅黑樹問題

面試題——輕鬆搞定面試中的紅黑樹問題

 連續兩次面試都問到了紅黑樹,關鍵兩次都沒有答好,這次就完整地來學習整理一下。

沒有學習過紅黑樹的同學請參考:

<<Introduction to Algorithms>> Chapter 13 Red-Black Trees Chapter 14 Augmenting Data Structures

1.stl中的set底層用的什麼資料結構?

2.紅黑樹的資料結構怎麼定義的?

3.紅黑樹有哪些性質?

4.紅黑樹的各種操作的時間複雜度是多少?

5.紅黑樹相比於BST和AVL樹有什麼優點?

6.紅黑樹相對於雜湊表,在選擇使用的時候有什麼依據?

7.如何擴充套件紅黑樹來獲得比某個結點小的元素有多少個?

8.擴充套件資料結構有什麼步驟?

9 為什麼一般hashtable的桶數會取一個素數

詳細解答

1.stl中的set底層用的什麼資料結構?

紅黑樹

2.紅黑樹的資料結構怎麼定義?

  1. enum Color  
  2. {  
  3.           RED = 0,  
  4.           BLACK = 1  
  5. };  
  6. struct RBTreeNode  
  7. {  
  8.            struct RBTreeNode*left, *right, *parent;  
  9.            int   key;  
  10.            int data;  
  11.            Color color;  
  12. };  

3.紅黑樹有哪些性質?

一般的,紅黑樹,滿足以下性質,即只有滿足以下全部性質的樹,我們才稱之為紅黑樹:
1)每個結點要麼是紅的,要麼是黑的。
2)根結點是黑的。
3)每個葉結點(葉結點即指樹尾端NIL指標或NULL結點)是黑的。
4)如果一個結點是紅的,那麼它的倆個兒子都是黑的。
5)對於任一結點而言,其到葉結點樹尾端NIL指標的每一條路徑都包含相同數目的黑結點。

4.紅黑樹的各種操作的時間複雜度是多少?

能保證在最壞情況下,基本的動態幾何操作的時間均為O(lgn)

5.紅黑樹相比於BST和AVL樹有什麼優點?

紅黑樹是犧牲了嚴格的高度平衡的優越條件為代價,它只要求部分地達到平衡要求,降低了對旋轉的要求,從而提高了效能。紅黑樹能夠以O(log2 n)的時間複雜度進行搜尋、插入、刪除操作。此外,由於它的設計,任何不平衡都會在三次旋轉之內解決。當然,還有一些更好的,但實現起來更復雜的資料結構能夠做到一步旋轉之內達到平衡,但紅黑樹能夠給我們一個比較“便宜”的解決方案。

相比於BST,因為紅黑樹可以能確保樹的最長路徑不大於最短路徑的長度兩倍,所以可以看出它的查詢效果是有最低保證的。在最壞的情況下也可以保證O(logN)的,這是要好於二叉查詢樹的。因為二叉查詢樹最壞情況可以讓查詢達到O(N)。

紅黑樹的演算法時間複雜度和AVL相同,但統計效能比AVL樹更高,所以在插入和刪除中所做的後期維護操作肯定會比紅黑樹要耗時好多,但是他們的查詢效率都是O(logN),所以紅黑樹應用還是高於AVL樹的. 實際上插入 AVL 樹和紅黑樹的速度取決於你所插入的資料.如果你的資料分佈較好,則比較宜於採用 AVL樹(例如隨機產生系列數),但是如果你想處理比較雜亂的情況,則紅黑樹是比較快的

對於一般的二叉搜尋樹(Binary Search Tree),其期望高度(即為一棵平衡樹時)為log2n,其各操作的時間複雜度(O(log2n))同時也由此而決定。但是,在某些極端的情況下(如在插入的序列是有序的時),二叉搜尋樹將退化成近似鏈或鏈,此時,其操作的時間複雜度將退化成線性的,即O(n)。我們可以通過隨機化建立二叉搜尋樹來儘量的避免這種情況,但是在進行了多次的操作之後,由於在刪除時,我們總是選擇將待刪除節點的後繼代替它本身,這樣就會造成總是右邊的節點數目減少,以至於樹向左偏沉。這同時也會造成樹的平衡性受到破壞,提高它的操作的時間複雜度平衡二叉搜尋樹(Balanced Binary Tree)具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。常用演算法有紅黑樹、AVL、Treap、伸展樹等。在平衡二叉搜尋樹中,我們可以看到,其高度一般都良好地維持在O(log(n)),大大降低了操作的時間複雜度。紅黑樹是一種自平衡二叉查詢樹,是在電腦科學中用到的一種資料結構,典型的用途是實現關聯陣列。它是在1972年由Rudolf Bayer發明的,他稱之為"對稱二叉B樹",它現代的名字是在 Leo J. Guibas 和 Robert Sedgewick 於1978年寫的一篇論文中獲得的。它是複雜的,但它的操作有著良好的最壞情況執行時間,並且在實踐中是高效的: 它可以在O(log n)時間內做查詢,插入和刪除,這裡的n是樹中元素的數目。

AVL

AVL是最先發明的自平衡二叉查詢樹演算法。在AVL中任何節點的兩個兒子子樹的高度最大差別為一,所以它也被稱為高度平衡樹,n個結點的AVL樹最大深度約1.44log2n。查詢、插入和刪除在平均和最壞情況下都是O(log n)。增加和刪除可能需要通過一次或多次樹旋轉來重新平衡這個樹。

6.紅黑樹相對於雜湊表,在選擇使用的時候有什麼依據?

權衡三個因素: 查詢速度, 資料量, 記憶體使用,可擴充套件性。
  總體來說,hash查詢速度會比map快,而且查詢速度基本和資料量大小無關,屬於常數級別;而map的查詢速度是log(n)級別。並不一定常數就比log(n) 小,hash還有hash函式的耗時,明白了吧,如果你考慮效率,特別是在元素達到一定數量級時,考慮考慮hash。但若你對記憶體使用特別嚴格, 希望程式儘可能少消耗記憶體,那麼一定要小心,hash可能會讓你陷入尷尬,特別是當你的hash物件特別多時,你就更無法控制了,而且 hash的構造速度較慢。

紅黑樹並不適應所有應用樹的領域。如果資料基本上是靜態的,那麼讓他們待在他們能夠插入,並且不影響平衡的地方會具有更好的效能。如果資料完全是靜態的,例如,做一個雜湊表,效能可能會更好一些。

在實際的系統中,例如,需要使用動態規則的防火牆系統,使用紅黑樹而不是散列表被實踐證明具有更好的伸縮性。Linux核心在管理vm_area_struct時就是採用了紅黑樹來維護記憶體塊的。

紅黑樹通過擴充套件節點域可以在不改變時間複雜度的情況下得到結點的秩。

7.如何擴充套件紅黑樹來獲得比某個結點小的元素有多少個?

這其實就是求節點元素的順序統計量,當然任意的順序統計量都可以需要在O(lgn)時間內確定。

在每個節點新增一個size域,表示以結點 x 為根的子樹的結點樹的大小,則有

size[x] = size[[left[x]] + size [right[x]] + 1;

這時候紅黑樹就變成了一棵順序統計樹。

利用size域可以做兩件事:

1). 找到樹中第i小的結點;

  1. OS-SELECT(x;,i)  
  2. r = size[left[x]] + 1;  
  3. if i == r  
  4.      return x  
  5. elseif i < r  
  6.      return OS-SELECT(left[x], i)  
  7. else return OS-SELECT(right[x],  i)  


思路:size[left[x]]表示在對x為根的子樹進行中序遍歷時排在x之前的個數,遞迴呼叫的深度不會超過O(lgn);

2).確定某個結點之前有多少個結點,也就是我們要解決的問題;

  1. OS-RANK(T,x)  
  2. r = x.left.size + 1;  
  3. y = x;  
  4. while y != T.root  
  5.          if y == y.p.right  
  6.                  r = r + y.p.left.size +1  
  7.          y = y.p  
  8. return r  

思路:x的秩可以視為在對樹的中序遍歷種,排在x之前的結點個數加上一。最壞情況下,OS-RANK執行時間與樹高成正比,所以為O (lgn).

8.擴充套件資料結構有什麼步驟?

1).選擇基礎資料結構;

2).確定要在基礎資料結構種新增哪些資訊;

3).驗證可用基礎資料結構上的基本修改操作來維護這些新新增的資訊;

4).設計新的操作。

9 為什麼一般hashtable的桶數會取一個素數

設有一個雜湊函式
H( c ) = c % N;
當N取一個合數時,最簡單的例子是取2^n,比如說取2^3=8,這時候
H( 11100(二進位制) ) = H( 28 ) = 4
H( 10100(二進位制) ) = H( 20 )= 4

這時候c的二進位制第4位(從右向左數)就”失效”了,也就是說,無論第c的4位取什麼值,都會導致H( c )的值一樣.這時候c的第四位就根本不參與H( c )的運算,這樣H( c )就無法完整地反映c的特性,增大了導致衝突的機率.

取其他合數時,都會不同程度的導致c的某些位”失效”,從而在一些常見應用中導致衝突.
但是取質數,基本可以保證c的每一位都參與H( c )的運算,從而在常見應用中減小衝突機率..

(個人意見:有時候不取質數效率也不會太差..但是無疑取質數之比較保險的..)