日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

STL-红黑树源码实现

發(fā)布時(shí)間:2024/4/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STL-红黑树源码实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

紅黑樹的介紹

它是一種特殊的二叉查找樹,紅黑樹的每個(gè)節(jié)點(diǎn)上都有存儲(chǔ)位表示節(jié)點(diǎn)的顏色,可以是紅或者黑。

紅黑樹的特性

1.每個(gè)節(jié)點(diǎn)或者黑色或者紅色

2.根節(jié)點(diǎn)是黑色

3.每個(gè)葉子節(jié)點(diǎn)是黑色

4.如果一個(gè)節(jié)點(diǎn)是紅色,它的子節(jié)點(diǎn)必須是黑色的

5.從一個(gè)節(jié)點(diǎn)到該節(jié)點(diǎn)的子孫節(jié)點(diǎn)的所有路徑上包含相同數(shù)目的黑節(jié)點(diǎn)

紅黑樹的操作

左旋

對(duì)x進(jìn)行左旋,意味著“將X變?yōu)橐粋€(gè)左節(jié)點(diǎn)”

右旋

平衡調(diào)節(jié)

新插入X,父節(jié)點(diǎn)P,G是P的父節(jié)點(diǎn),S是G的另外一個(gè)子節(jié)點(diǎn)。

新節(jié)點(diǎn)x必須為葉節(jié)點(diǎn),插入的節(jié)點(diǎn)必須為紅色;

如果P是紅色,必須調(diào)整紅色,根據(jù)X的插入位置,有4種情況:

1:S為黑色且X為外側(cè)插入,先對(duì)P,G左一次單旋轉(zhuǎn),在更改P,G顏色,重新滿足紅黑樹的規(guī)則3:

2.S為黑且X為內(nèi)側(cè)插入,先對(duì)P,X做一次單旋轉(zhuǎn)并更改G,X顏色,再將結(jié)果對(duì)G做一次單旋轉(zhuǎn),滿足紅黑樹的規(guī)則

3.S為紅色,且X為外側(cè)插入,先對(duì)P和G做一次單旋轉(zhuǎn),并改變X的顏色,此時(shí),如果GG(G的父節(jié)點(diǎn))為黑色,符合規(guī)則;否則,進(jìn)入情況4

?

或者

4.S為紅色且X為外側(cè)插入,先對(duì)P和G做一次單旋轉(zhuǎn),并改變X的顏色,如果G的父節(jié)點(diǎn),仍然為紅色,繼續(xù)往上做,直到父子連續(xù)部位紅的情況。

或者

?

紅黑樹的實(shí)現(xiàn)

節(jié)點(diǎn)的定義

struct _Node {
?? ??? ?_Nodeptr _Left, _Parent, _Right;
?? ??? ?_Ty _Value;
?? ??? ?_Redbl _color;
?? ?};

節(jié)點(diǎn)的父節(jié)點(diǎn),左右孩子節(jié)點(diǎn)

?

初始化

申請(qǐng)一個(gè)節(jié)點(diǎn),賦值給_Nil, 并且左右子節(jié)點(diǎn)為0;并在構(gòu)造一個(gè)節(jié)點(diǎn)_Head,并且設(shè)置為紅色節(jié)點(diǎn),父指針指向_Nil節(jié)點(diǎn),左右子節(jié)點(diǎn)都指向自己。

_Head節(jié)點(diǎn)和紅黑樹的根節(jié)點(diǎn)的父節(jié)點(diǎn),是相互指向。

_Nil用來表示null節(jié)點(diǎn)。

_Lmost,指向最左邊的節(jié)點(diǎn),_Rmost,指向最右邊的節(jié)點(diǎn),可以用來求最小和最大值。

void _Init() {
?? ??? ?_Nodeptr _Tmp = _Buynode(0, _Black);
?? ??? ?{
?? ??? ??? ?_Lockit _Lk;
?? ??? ??? ?if (_Nil == 0) {
?? ??? ??? ??? ?_Nil = _Tmp;
?? ??? ??? ??? ?_Tmp = 0;
?? ??? ??? ??? ?_Left(_Nil) = 0, _Right(_Nil) = 0;
?? ??? ??? ?}
?? ??? ??? ?++_Nilerefs;
?? ??? ?}
?? ??? ?if (_Tmp != 0) {
?? ??? ??? ?_Freenode(_Tmp);
?? ??? ?}
?? ??? ?_Head = _Buy(_Nil, _Red), _Size = 0;
?? ??? ?_Lmost() = _Head, _Rmost() = _Head;
?? ?}

數(shù)據(jù)的插入

實(shí)現(xiàn)左旋

_Nodeptr _Y = _Right(_X);
?? ??? ?_Right(_X) = _Left(_Y);
?? ??? ?if (_Left(_Y) != _Nil) {
?? ??? ??? ?_Parent(_Left(_Y)) = _X;
?? ??? ?}
?? ??? ?_Parent(_Y) = _Parent(_X);
?? ??? ?if (_X == _Root()) {
?? ??? ??? ?_Root() = _Y;
?? ??? ?}
?? ??? ?else if (_X == _Left(_Parent(_X))) {
?? ??? ??? ?_Left(_Parent(_X)) = _Y;
?? ??? ?}
?? ??? ?else {
?? ??? ??? ?_Right(_Parent(_X)) = _Y;
?? ??? ?}
?? ??? ?_Left(_Y) = _X;
?? ??? ?_Parent(_X) = _Y;
?? ?}

實(shí)現(xiàn)右旋

void _Rrotate(_Nodeptr _X) {
?? ??? ?_Nodeptr _Y = _Left(_X);
?? ??? ?_Left(_X) = _Right(_Y);
?? ??? ?if (_Right(_Y) != _Nil) {
?? ??? ??? ?_Parent(_Right(_Y)) = _X;
?? ??? ?}
?? ??? ?_Parent(_Y) = _Parent(_X);
?? ??? ?if (_X == _Root())
?? ??? ??? ?_Root() = _Y;
?? ??? ?else if (_X == _Right(_Parent(_X))) {
?? ??? ??? ?_Right(_Parent(_X)) = _Y;
?? ??? ?}
?? ??? ?else {
?? ??? ??? ?_Left(_Parent(_X)) = _Y;
?? ??? ?}
?? ??? ?_Right(_Y) = _X;
?? ??? ?_Parent(_X) = _Y;
?? ?}

紅黑樹刪除

紅黑樹的刪除分為兩種情況,情況1是有兩個(gè)子的情況,情況2最多有一個(gè)子樹的情況

?_Nodeptr _X;
?? ??? ?_Nodeptr _Y = (_P++)._Mynode();
?? ??? ?_Nodeptr _Z = _Y;

_Y:表示的是要?jiǎng)h除的節(jié)點(diǎn),_P表示的是臨近_Y的大的節(jié)點(diǎn)

_Z:賦值為_Y

情況1:最多有一個(gè)子樹的情況

  • ? ?如果左子樹或者右子樹為空的情況? ?

if (_Left(_Y) == _Nil) {
?? ??? ??? ?_X = _Right(_Y);
?? ??? ?}
?? ??? ?else if (_Right(_Y) == _Nil) {
?? ??? ??? ?_X = _Left(_Y);
?? ??? ?}

?

把_X分別設(shè)置為右子樹和左子樹。

  • 然后把_X的父節(jié)點(diǎn),設(shè)置為_Y的父節(jié)點(diǎn)即可;

? ? ? _Parent(_X) = _Parent(_Y);

  • 特殊情況判斷,如果為root()節(jié)點(diǎn)

if (_Root() == _Z)
?? ??? ??? ??? ?_Root() = _X;

否則就設(shè)置_Z的左右子樹

else if (_Left(_Parent(_Z)) == _Z) {
?? ??? ??? ??? ?_Left(_Parent(_Z)) = _X;
?? ??? ??? ?}
?? ??? ??? ?else {
?? ??? ??? ??? ?_Right(_Parent(_Z)) = _X;
?? ??? ??? ?}

  • 判斷是否為_Lmost??

if (_Lmost() != _Z) {
?? ??? ??? ??? ?;
?? ??? ??? ?}

如果_Z是_Lmost就把_Z的父節(jié)點(diǎn),設(shè)置為_Lmost
?? ??? ??? ?else if (_Right(_Z) == _Nil) {
?? ??? ??? ??? ?_Lmost() = _Parent(_Z);
?? ??? ??? ?}
?? ??? ??? ?else {
?? ??? ??? ??? ?_Lmost() = _Min(_X);
?? ??? ??? ?}

_Rmost的判斷是同樣的。

情況2:有兩個(gè)子樹的情況


?? ??? ??? ?_Y = _Min(_Right(_Y));
?? ??? ??? ?_X = _Right(_Y);

去_Y的右子樹的最小節(jié)點(diǎn),然后把_X置為該節(jié)點(diǎn)的右數(shù),_Z是要?jiǎng)h除的節(jié)點(diǎn)。目的是把_Y這個(gè)節(jié)點(diǎn),放到_Z的位置上去;接下來就是要調(diào)整,_Z,_Y的左右子樹和父節(jié)點(diǎn)的指向。

  • 更新_Z的左右子樹的父節(jié)點(diǎn)的指向?yàn)開Y

_Parent(_Left(_Z)) = _Y;

  • 更新_Y的左子樹的指向?yàn)開Z的左子樹的指向

?_Left(_Y) = _Left(_Z);

  • 如果恰好_Y==_Right(_Z)

if (_Y == _Right(_Z)) {
?? ??? ??? ??? ?_Parent(_X) = _Y;
?? ??? ??? ?}

  • 否則

? ? ? ? ? ? ? ? ? ? _Parent(_X) = _Parent(_Y);
?? ??? ??? ??? ??? ?_Left(_Parent(_Y)) = _X;
?? ??? ??? ??? ??? ?_Right(_Y) = _Right(_Z);
?? ??? ??? ??? ??? ?_Parent(_Right(_Z)) = _Y;

刪除后平衡調(diào)整

如果刪除的是黑色節(jié)點(diǎn),才需要進(jìn)行平衡調(diào)整。

分析左子樹的情況:

while (_X != _Root() && _Color(_X) == _Black) {
?? ??? ??? ??? ?if (_X == _Left(_Parent(_X))) {

  • 獲取_X節(jié)點(diǎn)的父節(jié)點(diǎn)的右子樹

_Nodeptr _W = _Right(_Parent(_X));

  • 如果_W的顏色是紅色

_Color(_W) = _Black;
?? ??? ??? ??? ??? ??? ?_Color(_Parent(_X)) = _Red;
?? ??? ??? ??? ??? ??? ?_Lrotate(_Parent(_X));
?? ??? ??? ??? ??? ??? ?_W = _Right(_Parent(_X));

if (_Color(_Left(_W)) == _Black&&_Color(_Right(_W)==_Black) {
?? ??? ??? ??? ??? ??? ?_Color(_W)=_Red;
?? ??? ??? ??? ??? ??? ?_X=_Parent(_X);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?else {
?? ??? ??? ??? ??? ??? ?if (_Color(_Right(_W)) == _Black) {
?? ??? ??? ??? ??? ??? ??? ?_Color(_Left(_W))=_Black;
?? ??? ??? ??? ??? ??? ??? ?_Color(_W)=_Red;
?? ??? ??? ??? ??? ??? ??? ?_Rrotate(_W);
?? ??? ??? ??? ??? ??? ??? ?_W=_Right(_Parent(_X));
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?_Color(_W) = _Color(_Parent(_X));
?? ??? ??? ??? ??? ??? ?_Color(_Parent(_X)) = _Black;
?? ??? ??? ??? ??? ??? ?_Color(_Right(_W)) = _Black;
?? ??? ??? ??? ??? ??? ?_Lrotate(_Parent(_X));
?? ??? ??? ??? ??? ??? ?break;

?? ??? ??? ??? ??? ?}

總結(jié)

以上是生活随笔為你收集整理的STL-红黑树源码实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。