【演算法導論】 第十課 平衡搜尋樹,演算法導論
樹的結構,如果不能保持平衡,那麼其搜尋效能會大大打折扣,而本節課介紹了幾種經典的平衡樹,如AVL,2-3-4tree,紅/黑樹狀結構等等,然後著重講了紅/黑樹狀結構,接下來就紅/黑樹狀結構的基本性質,作一些簡短的總結。
首先,紅/黑樹狀結構除了具有BST的基本性質外,還額外擁有以下的五大基本性質:
1)每個結點有一個色域,一個結點要麼為黑結點,要麼為紅結點
2)根節點為黑結點
3)每個葉子結點都為黑結點(無鍵值)
4)每個紅結點的父親都為黑結點,即不可能出現兩個紅色結點相連的情況
5)從根節點到任意分葉節點的路徑中的黑色結點數目相等,這個數目也稱為黑高度
由以上5點性質,可以保證紅/黑樹狀結構的高度為O(lgn),證明如下:
將紅/黑樹狀結構的所有紅結點,都與其父節點(由性質四得其父節點必定為黑)合并,可以得到一顆2-3-4 tree(即每個結點的子節點數目為2~4個),由資料結構知識可得,原紅/黑樹狀結構的葉子結點個數為帶鍵值結點個數n+1,假設整棵樹高度為h,那麼葉子結點數應為h^2~h^4,因此有h^2<=n+1<=h^4,即此時樹高度最高也只有log n+1,即樹的黑高度為log n+1,根據性質3,樹最高情況也不過是紅黑相間的時候,因此其高度最高只有2log n+1 ,即樹的高度為O(lgn)。
紅/黑樹狀結構的查詢操作和普通BST一樣,而刪除和插入操作則相對複雜,因為我們要保證紅/黑樹狀結構的5大性質,為什麼需要保證這五大性質呢?因為這五大性質是紅/黑樹狀結構為平衡樹的保證,能夠保證紅/黑樹狀結構的高度為Olgn,這樣紅/黑樹狀結構的基本操作(刪,插,查)都可以保證在Olgn的時間複雜度內完成。
接下來簡單介紹一下插入操作是如何完成的,刪除操作思路類似:
插入操作的原理就是插入一個紅結點,然後通過向上重染色和旋轉的方式維持紅/黑樹狀結構的性質
這裡有三種情況
case1 直線型 且祖父結點為黑,父節點和父親兄弟結點為紅 將祖父結點的黑傳遞到兩個紅子節點 每次向上傳 遞2個結點,樹高度2lgn 所以操作為O(lgn)
case2 zigzag Z型 父親兄弟結點為黑 旋轉為case3 O(1)的旋轉
case3 zigzig直線型 旋轉
由以上三種情況可得,插入的時間複雜度為重染色的Olgn+不超過3次的O(1)的旋轉操作
這裡值得一提的是,在實際的運用中,雖然向上重染色理論上花費的時間多於旋轉,但是當多個使用者並發查詢訪問紅/黑樹狀結構的時候,重染色並不會影響查詢,因為使用者並不關心每個結點的顏色,但是旋轉需要鎖定該子樹及其結點,可能會影響並發查詢的操作。
最後,就AVL和紅/黑樹狀結構做一下比較,就平衡程度而言,AVL是追求的絕對平衡,任意葉子結點的深度不會多於其他葉子結點深度+1,而紅/黑樹狀結構只要求局部平衡,其紅黑性保證了其平衡性,因此在維護平衡方面,紅/黑樹狀結構只需要不超過3次旋轉即可,這一點是AVL樹所做不到的,但查詢方面,由於AVL是絕對平衡,因此效率會略高於紅/黑樹狀結構,實際應用中這一點並不明顯,就統計效能而言,紅/黑樹狀結構會優於AVL,而C++ STL中的set、multiset、map、multimap等,都是紅/黑樹狀結構的一種變體。
值得一提的是,平衡樹都是動態資料結構,其優勢在於動態操作下,也能保持優越的查詢效率,如果是待用資料,那麼使用hash表效率會更高一些。