紅黑樹(沒有一條路徑會比其他路徑長2倍)是一種平衡二叉樹,它在計算機中被廣泛的應用!
結點採用的結構:
struct rb_node
紅黑樹的五大性質是學習紅黑樹最重要最基礎的,一定要背下來,方便在插入刪除的時候保持這五大性質。
1、每個結點的顏色是紅色或者黑色。
2、根結點是黑色。
3、每個葉結點都是黑色
4、紅色結點的子結點都是黑色。
5、對每乙個結點,從該結點到其後代所有的葉子結點的簡單路徑上,都包含相同數目的黑色結點。
說明:根結點的父結點和所有葉子結點的子結點都指向同乙個哨兵結點t.nil,當然這個哨兵結點的顏色為黑色。
旋轉是一種能保持二叉搜尋樹性質的搜尋樹區域性操作。
旋轉分為左旋和右旋
左旋的偽**如下:
left-rotate(t,x)
右旋只需要對換rightleft
插入操作與一般二叉樹的操作類似
rb_insert(t,z)
需要調整的情況是:當它的父結點是red時
由此可以分為8種情況:前4種與後4種左右對稱
前4種:
後4種:
與前4種完全對稱
演算法:
rb_insert_fixup(t,z)//見演算法導論179頁
while(z.p.color=="red")
if(z.p.p.left=z.p)前4種
y=z.p.p.right;
if(y.color=="red") //case1
y.color="black";
z.p.color="black";
z.p.p.color="red";
z=z.p.p;
else
if(z.p.right==z)//case2
z=z.p;
left_rotate(t,z);
z.p.color="black";//case3
z.p.p.color="red";
right_rotate(t,z.p.p);
else 後4種
y=z.p.p.left;
if(y.color=="red") //case1
y.color="black";
z.p.color="black";
z.p.p.color="red";
z=z.p.p;
else
if(z=z.p.left)//case2
z=z.p;//!!!
right_rotate(t,z);
z.p.color="black";//case3
z.p.p.color="red";
left_rotate(t,z.p.p);
t.root.color="black";
//如果要多值進行修改傳遞指標即可,如果要對不是全域性變數指標進行修改要加&
#include using namespace std;
struct rb_node
rb_node():left(null),right(null),p(null),color("black"){};//nil專用初始化函式
};struct rb_tree
void inorder(rb_node * k)
rb_node *root;//根結點
rb_node *nil;//集中所有頭的結點
};void rb_insert_fixup(rb_tree &t,rb_node *z);//插入的調整 見演算法導論178頁
void left_rotate(rb_tree &t,rb_node *z);//左旋
void right_rotate(rb_tree &t,rb_node *z);//右旋
void rb_insert(rb_tree &t,rb_node *z)//不加&
z->p=y; //設定z的父結點
//判斷z是父結點的左還有右子結點
if(y==t.nil)
t.root=z;
else if(y->key>z->key)
y->left=z;
else
y->right=z;
z->color="red";//開始為red
z->left=t.nil;
z->right=t.nil;
rb_insert_fixup(t,z);//如果y紅色,破壞性質(因為z也是red),調整
}void rb_insert_fixup(rb_tree &t,rb_node *z)//見演算法導論179頁
else
z->p->color="black";//case3
z->p->p->color="red";
right_rotate(t,z->p->p);
}}
else
else
z->p->color="black";//case3
z->p->p->color="red";
left_rotate(t,z->p->p);
}} }
t.root->color="black";
}void left_rotate(rb_tree &t,rb_node *x)//左旋 見演算法導論177頁
//將left_rotate中righteft ,就可以得到右旋
void right_rotate(rb_tree &t,rb_node *x)//右旋
主函式:
int main()
{ rb_tree t;
cout <
第十三章 併發
13.1 動機 13.2 基本執行緒 如果必須要控制現成的執行順序,最好是根本不用執行緒,而是自己編寫特定順序彼此控制的協作子程式。繼承thread類或者實現runnable介面。內部類實現。13.3 共享受限資源 1 如果要對類中的某個方法進行同步控制,最好同步所有方法。如果忽略了其中乙個,通常很...
第十三章 類
1.類簡單地說是乙個性的資料型別。類當中有資料成員,和成員函式。類的基本思想就是體現出資料的抽象和封裝。2.這裡只需要說明乙個問題即可 就是類成員函式的const型別 class screen public const int get const int i const int j const 這裡...
第十三章 事件
1 事件的作用 事件是對委託的封裝,如同屬性對字段的封裝。封裝後可以在委託上實現更複雜的邏輯。1.1 封裝訂閱 委託允許使用 對其進行賦值,但向乙個委託例項賦值多個委託時,使用 會造成覆蓋之前的委託。事件只支援 或 對事件進行賦值 1.2 封裝發布 委託可以在其他類進行訪問,而事件可以確保只有包容類...