//算法
// RB_tree.cppspa
// 筆記it
//二叉樹
// Created by fam on 15/3/17.margin
//top
//紅黑樹
//RB_tree時間
{co
/*算法導論
RB_tree概述:
RB_tree是一種平衡二叉樹,必須知足4個條件:
1:每一個節點不是紅色就是黑色
2:根節點爲黑色(葉子節點也爲黑色)
3:若是節點爲紅,其子節點必須爲黑(也就是說不能同時出現兩個紅色節點)
4:每一個節點 到達葉子節點的 每一條路徑 必須擁有一樣數量的 黑色節點 (這個數量(不包含本身)稱之爲黑高)
在平衡RB_tree的時候能夠先從上到下進行調整,每次遇到一個節點的子節點都是紅色的
就把這個節點改爲紅色,把子節點改爲黑色。 若是該節點的父節點也是紅色,
就作一次(也有多是兩次)旋轉。
這樣作的目的是,儘量讓紅色節點上移,這樣紅色節點就會變少,此時插入黑色須要調整的就少了
*/
//一下是算法導論中的紅黑樹筆記:
//哨兵
/*
哨兵:
爲了方便處理紅黑樹中的邊界條件,使用一個哨兵(T.nil)來表示葉子節點,T.nil擁有和普通節點同樣的屬性
color屬性爲black,其餘屬性能夠爲任意值,這樣能夠把葉子節點視爲一個普通的節點,可是爲了節省空間,能夠把
全部葉子節點和根節點的父節點設置爲同一個哨兵(T.nil)。
*/
//紅黑樹的高度
/*
樹高h最大爲2lg(n+1):
先用概括法證實每一個x節點至少包含 2^(bh(x))-1 個子節點(bh==blackheight)
1:若是bh(x)爲0,也就是x爲T.nil,x擁有 2^(0)-1 == 0個子節點
2:一個x的子節點的黑高爲 bh(x):{x爲紅色} 或 bh(x-1):{x爲黑色}
因此x擁有的自節點個數至少爲 2*2^(bh(x)-1)-1 == 2^(bh(x))-1
由此得證:每一個x節點至少包含 2^(bh(x))-1 個子節點
根據第3個條件,一條路徑至少包含一半的黑色節點 -->>
bh(x)>=h/2 -->> n>=2^(h/2)-1 -->> lg(n+1) >=h/2
-->> h<=2lg(n+1) (lg表示log2)
得證樹高最大爲2lg(n+1)
因此RB_tree全部操做時間爲O(lg(n));
*/
//左旋轉操做
//對x進行左旋轉
LEFT-ROTATE(T,x)
{
y=x.right; //拿到x的右兒子
x.right=y.left; //已知的有 x.right==y y.p==x 因此能夠先改變這兩個值
if(y.left!=T.nil) //若是y的左兒子爲nil就不須要給這個nil賦值一個parent
y.left.p=x;
y.p=x.p; //剩下的已知只有y.p 因此找到旋轉後的y.p就是如今的x.p
if(x.p == T.nil) //若是x.p是nil,表明x時根節點,因此旋轉後y就是根節點
T.root=y;
else if(x=x.p.left) //判斷x是的父節點的左兒子仍是右兒子
{
x.p.left=y;
}
else
{
x.p.right=y;
}
y.left=x; //y.left用完了(以前給x.right賦值完就能夠存放x了),拿來存放旋轉後的值(x);
x.p=y; //x.p用完了,能夠拿來存放旋轉後的值(y)了
}