第十三章 紅黑樹

2021-07-09 19:22:31 字數 3080 閱讀 5759

紅黑樹(沒有一條路徑會比其他路徑長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 封裝發布 委託可以在其他類進行訪問,而事件可以確保只有包容類...