版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第C++超詳細(xì)分析紅黑樹目錄紅黑樹紅黑樹的概念紅黑樹的性質(zhì)紅黑樹結(jié)點(diǎn)的定義紅黑樹的插入操作情況一情況二情況三紅黑樹的驗(yàn)證用紅黑樹封裝map、set紅黑樹的迭代器封裝map封裝set
紅黑樹
紅黑樹的概念
紅黑樹的概念紅黑樹,是一種二叉搜索樹,但在每個(gè)結(jié)點(diǎn)上增加一個(gè)存儲(chǔ)位表示結(jié)點(diǎn)的顏色,可以是Red或Black。通過(guò)對(duì)任何一條從根到葉子的路徑上各個(gè)結(jié)點(diǎn)著色方式的限制,紅黑樹確保沒(méi)有一條路徑會(huì)比其他路徑長(zhǎng)出倆倍,因而是接近平衡的。
紅黑樹和AVL樹都是高效的平衡二叉樹,增刪改查的時(shí)間復(fù)雜度都是O(),紅黑樹不追求絕對(duì)平衡,其只需保證最長(zhǎng)路徑不超過(guò)最短路徑的2倍,相對(duì)而言,降低了插入和旋轉(zhuǎn)的次數(shù),所以在經(jīng)常進(jìn)行增刪的結(jié)構(gòu)中性能比AVL樹更優(yōu),而且紅黑樹實(shí)現(xiàn)比較簡(jiǎn)單,所以實(shí)際運(yùn)用中紅黑樹更多。
紅黑樹的性質(zhì)
每個(gè)結(jié)點(diǎn)不是紅色就是黑色根節(jié)點(diǎn)是黑色的如果一個(gè)結(jié)點(diǎn)是紅色的,則它的兩個(gè)孩子結(jié)點(diǎn)是黑色的對(duì)于每個(gè)結(jié)點(diǎn),從該節(jié)點(diǎn)到其所有后代葉節(jié)點(diǎn)的簡(jiǎn)單路徑上,均包含相同數(shù)目的黑色結(jié)點(diǎn)每個(gè)葉子結(jié)點(diǎn)都是黑色的(此處的葉子節(jié)點(diǎn)指的是空結(jié)點(diǎn),如上圖路徑數(shù)為11條)
紅黑樹結(jié)點(diǎn)的定義
enumColor{
BLACK,
templateclassT
structRBTreeNode
RBTreeNodeT*_left;
RBTreeNodeT*_right;
RBTreeNodeT*_parent;
Color_col;
T_data;
RBTreeNode(constTdata)
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_col(RED)
,_data(data)
紅黑樹的插入操作
約定:cur為當(dāng)前節(jié)點(diǎn),p為父節(jié)點(diǎn),g為祖父節(jié)點(diǎn),u為叔叔節(jié)點(diǎn)
情況一
情況一:cur為紅,p為紅,g為黑,u存在且為紅注意:此處看到的樹,可能是一棵完整的樹,也可能是一棵子樹解決方式:將p,u改為黑,g改為紅,然后把g當(dāng)成cur,繼續(xù)向上調(diào)整
如果g是根節(jié)點(diǎn),調(diào)整完成后,需要將g改為黑色
如果g是子樹,g一定有雙親,且g的雙親如果是紅色,需要繼續(xù)向上調(diào)整。
情況二
情況二:cur為紅,p為紅,g為黑,u不存在/u為黑
解決方法:p為g的左孩子,cur為p的左孩子,則進(jìn)行右單旋;p為g的右孩子,cur為p的右孩子,則進(jìn)行左單旋。
p變黑,g變紅。
1.如果u節(jié)點(diǎn)不存在,則cur一定是新插入節(jié)點(diǎn),因?yàn)槿绻鹀ur不是新插入節(jié)點(diǎn),則cur和p一定有一個(gè)節(jié)點(diǎn)的顏色是黑色,就不滿足性質(zhì)4:每條路徑黑色節(jié)點(diǎn)個(gè)數(shù)相同。
2.如果u節(jié)點(diǎn)存在,則其一定是黑色的,cur一定不是新增節(jié)點(diǎn),那么cur節(jié)點(diǎn)原來(lái)的顏色一定是黑色的,是作為子樹的祖父,由第一種情況變化過(guò)來(lái)的
情況三
情況三:cur為紅,p為紅,g為黑,u不存在/u為黑(折線型)
p為g的左孩子,cur為p的右孩子,則針對(duì)p做左單旋轉(zhuǎn);
p為g的右孩子,cur為p的左孩子,則針對(duì)p做右單旋轉(zhuǎn)。
即轉(zhuǎn)換為了情況二。再對(duì)g做對(duì)于旋轉(zhuǎn)。即進(jìn)行雙旋轉(zhuǎn)。
//T-Kset
//T-pairconstK,Vmap
templateclassK,classT,classKeyOfT
classRBTree
typedefRBTreeNodeTNode;
public:
typedefRBTreeIteratorT,T,T*iterator;
typedefRBTreeIteratorT,constT,constT*const_iterator;
iteratorbegin();
iteratorend();
RBTree()
:_root(nullptr)
//拷貝構(gòu)造和賦值重載
//析構(gòu)
Node*Find(constKkey);
pairiterator,boolInsert(constTdata)
if(_root==nullptr)
_root=newNode(data);
_root-_col=BLACK;
returnmake_pair(iterator(_root),true);
Node*parent=nullptr;
Node*cur=_root;
KeyOfTkot;
while(cur)
if(kot(cur-_data)kot(data))
parent=cur;
cur=cur-_right;
elseif(kot(cur-_data)kot(data))
parent=cur;
cur=cur-_left;
else
returnmake_pair(iterator(cur),false);
//新增節(jié)點(diǎn),顏色是紅色,可能破壞規(guī)則3,產(chǎn)生連續(xù)紅色節(jié)點(diǎn)
cur=newNode(data);
Node*newnode=cur;
cur-_col=RED;
if(kot(parent-_data)kot(data))
parent-_right=cur;
cur-_parent=parent;
else
parent-_left=cur;
cur-_parent=parent;
//控制近似平衡
while(parentparent-_col==RED)
Node*grandfather=parent-_parent;
if(parent==grandfather-_left)
Node*uncle=grandfather-_right;
//情況一:uncle存在且為紅,進(jìn)行變色處理,并繼續(xù)往上更新處理
if(uncleuncle-_col==RED)
parent-_col=uncle-_col=BLACK;
grandfather-_col=RED;
cur=grandfather;
parent=cur-_parent;
}//情況二+三:uncle不存在,或者存在且為黑,需要旋轉(zhuǎn)+變色處理
else
//情況二:?jiǎn)涡?變色
if(cur==parent-_left)
RotateR(grandfather);
parent-_col=BLACK;
grandfather-_col=RED;
else//情況三:雙旋+變色
RotateL(parent);
RotateR(grandfather);
cur-_col=BLACK;
grandfather-_col=RED;
break;
else//(parent==grandfather-_right)
Node*uncle=grandfather-_left;
if(uncleuncle-_col==RED)
parent-_col=uncle-_col=BLACK;
grandfather-_col=RED;
cur=grandfather;
parent=cur-_parent;
else
if(parent-_right==cur)
RotateL(grandfather);
parent-_col=BLACK;
grandfather-_col=RED;
else
RotateR(parent);
RotateL(grandfather);
cur-_col=BLACK;
grandfather-_col=RED;
break;
_root-_col=BLACK;
returnmake_pair(iterator(newnode),true);
voidRotateR(Node*parent);
voidRotateL(Node*parent);
private:
Node*_root;
紅黑樹的驗(yàn)證
紅黑樹的檢測(cè)分為兩步:
檢測(cè)其是否滿足二叉搜索樹(中序遍歷是否為有序序列)檢測(cè)其是否滿足紅黑樹的性質(zhì)
此處用未改造過(guò)的紅黑樹
templateclassK,classV
structRBTreeNode
RBTreeNodeK,V*_left;
RBTreeNodeK,V*_right;
RBTreeNodeK,V*_parent;
Colour_col;
pairK,V_kv;
RBTreeNode(constpairK,Vkv)
:_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
,_col(RED)
,_kv(kv)
templateclassK,classV
classRBTree
typedefRBTreeNodeK,VNode;
public:
RBTree()
:_root(nullptr)
boolInsert(constpairK,Vkv);
voidRotateR(Node*parent);
voidRotateL(Node*parent);
void_InOrder(Node*root)
if(root==nullptr)
return;
_InOrder(root-_left);
coutroot-_kv.first"";
_InOrder(root-_right);
voidInOrder()
_InOrder(_root);
coutendl;
boolCheckRED_RED(Node*cur)
if(cur==nullptr)
returntrue;
if(cur-_col==REDcur-_parent-_col==RED)
cout"違反規(guī)則三,存在連續(xù)的紅色節(jié)點(diǎn)"endl;
returnfalse;
returnCheckRED_RED(cur-_left)
CheckRED_RED(cur-_right);
//檢查每條路徑黑色節(jié)點(diǎn)的數(shù)量
boolCheckBlackNum(Node*cur,intblackNum,intbenchmark){
if(cur==nullptr){
if(blackNum!=benchmark){
cout"違反規(guī)則四:黑色節(jié)點(diǎn)的數(shù)量不相等"endl;
returnfalse;}
returntrue;
if(cur-_col==BLACK)
++blackNum;
returnCheckBlackNum(cur-_left,blackNum,benchmark)
CheckBlackNum(cur-_right,blackNum,benchmark);
boolIsBalance()
if(_root==nullptr)
returntrue;
if(_root-_col==RED)
cout"根節(jié)點(diǎn)是紅色,違反規(guī)則二"endl;
returnfalse;
//算出最左路徑的黑色節(jié)點(diǎn)的數(shù)量作為基準(zhǔn)值
intbenchmark=0;
Node*cur=_root;
while(cur)
if(cur-_col==BLACK)
++benchmark;
cur=cur-_left;
intblackNum=0;
returnCheckRED_RED(_root)CheckBlackNum(_root,blackNum,benchmark);
private:
Node*_root;
voidTestRBTree1()
constintn=1000000;
vectorint
a.reserve(n);
srand(time(0));
for(size_ti=0;i++i)
a.push_back(rand());
RBTreeint,int
for(autoe:a)
t1.Insert(make_pair(e,e));
coutt1.IsBalance()endl;
//t1.InOrder();
用紅黑樹封裝map、set
紅黑樹的迭代器
begin()與end()
begin()可以放在紅黑樹中最小節(jié)點(diǎn)(即最左側(cè)節(jié)點(diǎn))的位置
end()放在最大節(jié)點(diǎn)(最右側(cè)節(jié)點(diǎn))的下一個(gè)位置
typedefRBTreeIteratorT,T,T*iterator;
typedefRBTreeIteratorT,constT,constT*const_iterator;
iteratorbegin()
Node*left=_root;
while(leftleft-_left)
left=left-_left;
//returnleft
returniterator(left);
iteratorend()
returniterator(nullptr);
操作符重載
templateclassT,classRef,classPtr
structRBTreeIterator
typedefRBTreeNodeTNode;
typedefRBTreeIteratorT,Ref,PtrSelf;
Node*_node;
RBTreeIterator(Node*node=nullptr)
:_node(node)
Refoperator*()
return_node-_data;
Ptroperator-()
return_node-_data;
Selfoperator--()
//跟++基本是反過(guò)來(lái)
return*this;
Selfoperator++()
if(_node-_right)
//右子樹中序第一個(gè)節(jié)點(diǎn),也就是右子樹的最左節(jié)點(diǎn)
Node*subLeft=_node-_right;
while(subLeft-_left)
subLeft=subLeft-_left;
_node=subLeft;
else
//當(dāng)前子樹已經(jīng)訪問(wèn)完了,要去找祖先訪問(wèn),沿著到根節(jié)點(diǎn)的路徑往上走,
//找孩子是父親左的那個(gè)父親節(jié)點(diǎn)
Node*cur=_node;
Node*parent=cur-_parent;
while(parentparent-_right==cur)
cur=parent;
parent=parent-_parent;
_node=parent;
return*this;
booloperator!=(constSelfs)const
return_node!=s._node;
booloperator==(constSelfs)const
return_node==s._node;
封裝map
#pragmaonce
#include"RBTree.h"
namespaceMyMap
templateclassK,classV
classmap
structMapKeyOfT
constKoperator()(constpairconstK,Vkv)
returnkv.first;
public:
typedeftypenameRBTreeK,pairconstK,V,MapKeyOfT::iteratoriterator;
iteratorbegin()
return_t.begin();
iteratorend()
return_t.end();
pairiterator,boolinsert(constpairconstK,Vkv)
return_t.Insert(kv);
Voperator[](constKkey)
pairiterator,boolret=_t.Insert(make_pair(key,V()));
returnret.first-second;
private:
RBTreeK,pairconstK,V,MapKeyOfT
voidtest_map()
mapstring,stringdict;
dict.insert(make_pair("sort","排序"));
dict.insert(make_pair("string","字符串"));
dict.insert(make_pair("debug","找蟲子"));
dict.insert(make_pair("set","集合"));
mapstring,string::iteratorit=dict.
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 安全員A證考試練習(xí)題附參考答案詳解(能力提升)
- 水電站防汛抗旱方案
- 安全員A證考試能力提升打印大全及參考答案詳解(培優(yōu)b卷)
- 房地產(chǎn)估價(jià)師考試密押題庫(kù)與答案解析比較法及其應(yīng)用(二)
- 施工現(xiàn)場(chǎng)物料利用率提升方案
- 2025年押題寶典安全員A證考試題庫(kù)【重點(diǎn)】附答案詳解
- 2025年網(wǎng)絡(luò)安全法規(guī)解讀試題及答案
- 安全員A證考試考前自測(cè)高頻考點(diǎn)模擬試題含完整答案詳解(奪冠)
- 安全員A證考試練習(xí)題(一)及答案詳解(典優(yōu))
- 熱力設(shè)施維護(hù)周期計(jì)劃
- 六年級(jí)寒假家長(zhǎng)會(huì)課件
- 物流鐵路專用線工程節(jié)能評(píng)估報(bào)告
- 2026天津市南開區(qū)衛(wèi)生健康系統(tǒng)招聘事業(yè)單位60人(含高層次人才)備考核心試題附答案解析
- 重瞼手術(shù)知情同意書
- DL-T976-2017帶電作業(yè)工具、裝置和設(shè)備預(yù)防性試驗(yàn)規(guī)程
- 《煤礦低濃度瓦斯管道輸送安全保障系統(tǒng)設(shè)計(jì)規(guī)范》
- 換電柜維護(hù)培訓(xùn)課件
- 土石方工程掛靠合同
- 招聘會(huì)會(huì)展服務(wù)投標(biāo)方案(技術(shù)標(biāo) )
- 企業(yè)標(biāo)準(zhǔn)-格式模板
- 軟件售后服務(wù)人員提成方案附表
評(píng)論
0/150
提交評(píng)論