接著上節講資料結構中的樹,要理解樹,最重要的是要理解:二叉排序樹、平衡二叉樹和紅/黑樹狀結構。今天就來討論這幾種樹。
二叉排序樹
概念:二叉排序樹又叫二叉尋找樹、二叉搜尋樹、二叉檢索樹。二叉排序樹是二叉樹的一個特化,二叉排序樹規定了每個結點的關鍵字均大於其左子樹上所有的結點的關鍵字,同時小於或等於其右子樹上所有結點的關鍵字。所以,從二叉排序樹的根結點一直往左走,直到底,就可以得到最小值;從根結點一起往右走,直到底,就可以得到最大值。二叉排序樹的這種特殊性質使得它在尋找元素方面的時候特別方便,每一次尋找都可以去掉一半的元素,因此尋找的時間是O(logN)。
二叉排序樹的演算法:
(1)二叉排序樹的尋找演算法
typedef struct Node
{
int data; //結點值
struct Node *parent; //父結點
struct Node *lchild; //左結點
struct Node *rchild; //右結點
}TREENODE;
TREENODE *Search(TREENODE *root,int value)
{
if(root!=NULL)
{
if(root->data==value)
{
return root;
}
else
{
if(value < root->data)
{
Search(root->lchild,value); //如果尋找值比結點值小,遞迴左子樹
}
else
{
Search(root->rchild,value); //如果尋找值比結點值大,遞迴右子樹
}
}
}
return root;
}
(2)二叉排序樹的插入演算法
二叉排序樹的插入演算法很簡單:從根結點開始,遇到索引值大的就往左,遇到索引值小的就往右。一直到底,就為插入點。
(3)二叉排序樹的刪除演算法
二叉排序樹的刪除演算法有點小複雜:根據所要刪除的結點有兩個子結點還是只有一個或者沒有子結點會有不同的處理。
<1> 有兩個子結點的情況:找到右子樹中值最小的一個結點,用它的值替代當前的結點值,然後再把這個值最小的結點刪除,也就是有兩個子結點的情況是用最小的一個大於當前結點的關鍵字的結點替代了當前的結點。
<2> 只有一個結點或者沒有子結點的情況就簡單多了,如果還有子結點就把子結點的位置往上挪,然後把當前結點刪除。
平衡二叉樹
概念:形態勻稱的二叉樹稱為平衡二叉樹,其嚴格定義是:一棵空樹是平衡二叉樹;若T是一棵非空二叉樹,其左、右子樹為TL和TR,令hl和hr分別為左、右子樹的深度,若且唯若:(1)TL、TR都是平衡二叉樹;(2)|hl-hr|≤1時,T是平衡二叉樹。
平衡二叉樹的旋轉:平衡二叉樹,在刪除一些結點後,破壞了樹的平衡,這個時候需要對樹進行調整,以維持樹的平衡。此時,用來調整樹的平衡的方法就是常說的樹的旋轉。
AVL樹:部落格園這篇文章講到:http://blog.csdn.net/do2jiang/article/details/5529770
紅/黑樹狀結構
概念:紅/黑樹狀結構(Red-Black Tree)是一種自平衡二叉樹。但需要注意的是,紅/黑樹狀結構並不是平衡二叉樹,恰恰相反,紅/黑樹狀結構放鬆了平衡二叉樹的某些要求,由於一定限度的“不平衡”,紅/黑樹狀結構的效能得到了提升。它的應用非常廣泛,如STL(標準模板庫)的map和set容器的記憶體儲存結構就是紅/黑樹狀結構。
如果一個結點沒有了子結點,則稱為葉子結點,因為它是在樹的邊緣上。在紅/黑樹狀結構中,葉子被假定為null或空。由於紅/黑樹狀結構也是二叉排序樹,它們當中每一個結點的值都必須大於或等於在它的左子樹中的所有結點,並且小於或等於在它的右子樹中的所有結點。這確保紅/黑樹狀結構能夠快速地在樹中尋找出指定的值。
滿足下列條件的二叉排序樹是紅/黑樹狀結構:
(1)每個結點要麼是“紅色”的,要麼是“黑色”的。
(2)所有的葉子結點都是空結點,並且是“黑色”的。
(3)如果一個結點是“紅色”的,那麼它的兩個子結點都是“黑色”的。
(4)任一結點到其葉子結點的每條路徑上都包含相同數目的“黑色”結點。
(5)根結點永遠是“黑色”的。
有了上面幾條規則,就可以保證整棵樹的平衡,也就等於保證了搜尋的時間為O(logN)。
下面就一棵紅/黑樹狀結構:
相關文章:
• C/C++ 一點筆記(1)
• C/C++ 一點筆記(2)