如果你已經掌握了紅黑樹前篇的內容,那麼很高興你已經具備了學習紅黑樹的資本。左旋轉和右旋轉是紅黑樹中為了調節紅黑個數而設計的方案,所以,此篇主要講解一下旋轉問題。旋轉是紅黑樹中最簡單的東東,不過也是最基礎的,由於涉及到紅黑樹的性質,所以先從學習紅黑樹的五個性質開始吧。
1,紅黑樹的五個性質:
1)每個結點要麼是紅的,要麼是黑的。
2)根結點是黑的。
3)每個葉結點,即空結點(nil)是黑的。
4)如果乙個結點是紅的,那麼它的倆個兒子都是黑的。
5)對每個結點,從該結點到其子孫結點的所有路徑上包含相同數目的黑結點。
2,紅黑樹的旋**
當我們在對紅黑樹進行插入、刪除等操作時,對樹做了修改,那麼可能會違背紅黑樹的性質。
為了保持紅黑樹的性質,我們可以通過對樹進行旋轉,即修改樹中某些結點的指標結構,同時需要更改某些節點的顏色,以達到對紅黑樹進行插入、刪除結點等操作時,紅黑樹依然能保持它特有的性質。
旋轉如下圖:
其中:旋轉過程中二叉搜尋樹(bst)性質不變:α≤x≤β≤y≤γ
我們以左旋為例進行解析,左旋如下圖:
圖中紅線標註的步驟如下(right[x]:x的右節點;p[x]:x的父節點):
①y←right[x]
②right[x]←left[y], p[left[y]]←x
③p[y]←p[x], p[x]的左或右指標指向y (p[x]為根節點則root←y)
④ left[y]←x, p[x]←y
經過此四個步驟即可完成左旋操作。
3,**實現:
//root:傳入的樹的根節點,x:旋轉的基點。
node* left_rotate( node* root, node* x )
//step1:記錄y的位置,其為x的右節點 == y←right[x]
y = x->right;
//step2:y的原來的左節點變為x的右節點 == right[x]←left[y]
x->right = y->left;
//y的原來的左節點的父節點變為x == p[left[y]]←x
if( y->left != &tree_nil )
y->left->parent = x;
//step3:原來的x的父結點變為現在的y的父結點 == p[y]←p[x]
y->parent = x->parent;
if( x->parent == &tree_nil )
root = y;
else if( x == x->parent->left )
x->parent->left = y;
else
x->parent->right = y;
//step4:x為y的左節點,y為x的父節點。
y->left = x;
x->parent = y;
return root;
}
4,左旋+節點顏色修改:
為什麼要旋轉,最終的目的還是為了實現紅黑樹的五個性質,以下圖為例解釋說明左旋操作:
此圖操作步驟為(主要對性質5進行說明,其餘性質一目了然):祖、父兩個節點互換顏色,最後對祖節點進行左旋轉。顏色互換後旋轉,是的為紅色的祖節點成了左子樹上的一點,左子樹新增紅節點不影響其黑節點個數。同時,對於右子樹來說,父變成了根節點,但是父變為了黑色,其黑節點個數依然不變。其中1由右邊改為了左邊,但是他的父節點的顏色是一直的,且其現在的父節點和原來父節點是兄弟關係,古其黑節點個數也不變。
5,右旋和左旋類似,不做敘述。
git學習 上篇
git簡介 是什麼 git是目前世界上最先進的分布式版本控制系統,通俗的說就是分布式管理 的軟體工具。它是linus公司用c語言兩周完成的。集中式版本控制系統和分布式版本控制系統的比較 集中式特點 版本庫必須集中存放在 伺服器 必須聯網工作 速度慢 安全性低 分布式特點 每台電腦都是乙個版本庫 無需...
紅黑樹 學習
紅黑樹筆記 紅黑樹是一顆二叉平衡樹,查詢不會破壞平衡性,所以和二叉平衡術查詢方式一致。從根節點開始查詢,為空就返回null,為當前值就返回,否則繼續向下查詢。如果當前節點的key為要查詢的節點的key,那麼直接返回當前值。如果當前節點的key大於要查詢的節點的key,那麼繼續向當前節點的左子節點查詢...
紅黑樹學習筆記
二叉樹,他的定義是每個節點最多只有兩個子樹 即左子樹和右子樹,當然也可以沒有子樹 如下圖是乙個簡單的二叉樹 對於這樣的資料結構,在c語言中通常這樣來定義結構體?1 2 3 4 5 typedefstruct binary tree binarytree 二叉搜尋樹,首先他也是乙個二叉樹,與二叉樹不同...