當(dāng)前位置:首頁 > 公眾號精選 > CPP開發(fā)者
[導(dǎo)讀]↓推薦關(guān)注↓std::set/std::map(以下用std::map代表)是常用的關(guān)聯(lián)式容器,也是ADT(抽象數(shù)據(jù)類型)。也就是說,其接口(不是OO意義下的interface)不僅規(guī)定了操作的功能,還規(guī)定了操作的復(fù)雜度(代價(jià)/cost)。例如set::insert(iterat...

推薦關(guān)注↓

select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzAxMDM0MzQ4Mg==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/DSU8cv1j3ibStMRcibJLd4TkNlt53KNZj0A2IicORH4REC4ics87icsx703M5giby2wuofz3dicMsHVcXDMXTM6t6VBQw/0?wx_fmt=png" data-nickname="開源前哨" data-alias="osfront" data-signature="點(diǎn)擊獲取10萬 star的開發(fā)資源庫。 日常分享熱門、有趣和實(shí)用的開源項(xiàng)目~" data-from="0">

std::set/std::map (以下用 std::map 代表) 是常用的關(guān)聯(lián)式容器,也是 ADT(抽象數(shù)據(jù)類型)。也就是說,其接口(不是 OO 意義下的 interface)不僅規(guī)定了操作的功能,還規(guī)定了操作的復(fù)雜度(代價(jià)/cost)。例如 set::insert(iterator first, iterator last) 在通常情況下是 O(N log N),N 是區(qū)間的長度;但是如果 [first, last) 已經(jīng)排好序(在 key_compare 意義下),那么復(fù)雜度將會(huì)是 O(N)。

盡管 C 標(biāo)準(zhǔn)沒有強(qiáng)求 std::map 底層的數(shù)據(jù)結(jié)構(gòu),但是根據(jù)其規(guī)定的時(shí)間復(fù)雜度,現(xiàn)在所有的 STL 實(shí)現(xiàn)都采用平衡二叉樹來實(shí)現(xiàn) std::map,而且用的都是紅黑樹。《算法導(dǎo)論(第 2 版)》第 12、13 章介紹了二叉搜索樹和紅黑樹的原理、性質(zhì)、偽代碼,侯捷先生的《STL 源碼剖析》第 5 章詳細(xì)剖析了 SGI STL 的對應(yīng)實(shí)現(xiàn)。本文對 STL 中紅黑樹(rb_tree)的實(shí)現(xiàn)問了幾個(gè)稍微深入一點(diǎn)的問題,并給出了我的理解。

本文剖析的是 G 4.7 自帶的這一份 STL 實(shí)現(xiàn)及其特定行為,與《STL 源碼剖析》的版本略有區(qū)別。為了便于閱讀,文中的變量名和 class 名都略有改寫(例如 _Rb_tree_node 改為 rb_tree_node)。本文不談紅黑樹的平衡算法,在我看來這屬于“旁枝末節(jié)”(見陳碩《談一談網(wǎng)絡(luò)編程學(xué)習(xí)經(jīng)驗(yàn)》對此的定義),因此也就不關(guān)心節(jié)點(diǎn)的具體顏色了。

數(shù)據(jù)結(jié)構(gòu)回顧

先回顧一下數(shù)據(jù)結(jié)構(gòu)教材上講的二叉搜索樹的結(jié)構(gòu),節(jié)點(diǎn)(Node)一般有三個(gè)數(shù)據(jù)成員(left、right、data),樹(Tree)有一到兩個(gè)成員(root 和 node_count)。

用 Python 表示:
class?Node:
????def?\_\_init\_\_\(self,?data\):
????????self.left?=?None
????????self.right?=?None
????????self.data?=?data

class?Tree:
????def?\_\_init\_\_\(self\):
????????self.root?=?None
????????self.node\_count?=?0
而實(shí)際上 STL rb_tree 的結(jié)構(gòu)比這個(gè)要略微復(fù)雜一些,我整理的代碼見 https://gist.github.com/4574621#file-tree-structure-cc ?。

節(jié)點(diǎn)

Node 有 5 個(gè)成員,除了 left、right、data,還有 color 和 parent。

C 實(shí)現(xiàn),位于bits/stl\_tree.h
/\*\*
?\*?Non-template?code
?\*\*/

enum?rb\_tree\_color?\{?kRed,?kBlack?\};

struct?rb\_tree\_node\_base
\{
??rb\_tree\_color???????color\_;
??rb\_tree\_node\_base\*??parent\_;
??rb\_tree\_node\_base\*??left\_;
??rb\_tree\_node\_base\*??right\_;
\};

/\*\*
?\*?template?code
?\*\*/

template\
struct?rb\_tree\_node?:?public?rb\_tree\_node\_base
\{
??Value?value\_field\_;
\};
見下圖。

node
color 的存在很好理解,紅黑樹每個(gè)節(jié)點(diǎn)非紅即黑,需要保存其顏色(顏色只需要 1-bit 數(shù)據(jù),一種節(jié)省內(nèi)存的優(yōu)化措施是把顏色嵌入到某個(gè)指針的最高位或最低位,Linux 內(nèi)核里的 rbtree 是嵌入到 parent 的最低位);parent 的存在使得非遞歸遍歷成為可能,后面還將再談到這一點(diǎn)。

Tree 有更多的成員,它包含一個(gè)完整的 rb_tree_node_base(color/parent/left/right),還有 node_count 和 key_compare 這兩個(gè)額外的成員。

這里省略了一些默認(rèn)模板參數(shù),如 key_compare 和 allocator。

template\?//?key\_compare?and?allocator
class?rb\_tree
\{
?public:
??typedef?std::less\?key\_compare;
??typedef?rb\_tree\_iterator\?iterator;
?protected:

??struct?rb\_tree\_impl?//?:?public?node\_allocator
??\{
????key\_compare???????key\_compare\_;
????rb\_tree\_node\_base?header\_;
????size\_t????????????node\_count\_;
??\};
??rb\_tree\_impl?impl\_;
\};
template\?//?key\_compare?and?allocator
class?map
\{
?public:
??typedef?std::pair\?value\_type;
?private:
??typedef?rb\_tree\?rep\_type;
??rep\_type?tree\_;
\};
見下圖。這是一顆空樹,其中陰影部分是 padding bytes,因?yàn)?key_compare 通常是 empty class。(allocator 在哪里?)

tree
rb_tree 中的 header 不是 rb_tree_node 類型,而是 rb_tree_node_base,因此 rb_tree 的 size 是 6 * sizeof(void*),與模板類型參數(shù)無關(guān)。在 32-bit 上是 24 字節(jié),在 64-bit 上是 48 字節(jié),很容易用代碼驗(yàn)證這一點(diǎn)。另外容易驗(yàn)證 std::set 和 std::map 的 sizeof() 是一樣的。

注意 rb_tree 中的 header 不是 root 節(jié)點(diǎn),其 left 和 right 成員也不是指向左右子節(jié)點(diǎn),而是指向最左邊節(jié)點(diǎn)(left_most)和最右邊節(jié)點(diǎn)(right_most),后面將會(huì)介紹原因,是為了滿足時(shí)間復(fù)雜度。header.parent 指向 root 節(jié)點(diǎn),root.parent 指向 header,header 固定是紅色,root 固定是黑色。在插入一個(gè)節(jié)點(diǎn)后,數(shù)據(jù)結(jié)構(gòu)如下圖。

tree1
繼續(xù)插入兩個(gè)節(jié)點(diǎn),假設(shè)分別位于 root 的左右兩側(cè),那么得到的數(shù)據(jù)結(jié)構(gòu)如下圖所示(parent 指針沒有全畫出來,因?yàn)槠渲赶蚝苊黠@),注意 header.left 指向最左側(cè)節(jié)點(diǎn),header.right 指向最右側(cè)節(jié)點(diǎn)。

tree3

迭代器

rb_tree 的 iterator 的數(shù)據(jù)結(jié)構(gòu)很簡單,只包含一個(gè) rb_tree_node_base 指針,但是其 /--操作卻不見得簡單(具體實(shí)現(xiàn)函數(shù)不在頭文件中,而在 libstdc 庫文件中)。

//?defined?in?library,?not?in?header
rb\_tree\_node\_base\*?rb\_tree\_increment\(rb\_tree\_node\_base\*?node\);
//?others:?decrement,?reblance,?etc.

template\
struct?rb\_tree\_node?:?public?rb\_tree\_node\_base
\{
??Value?value\_field\_;
\};

template\
struct?rb\_tree\_iterator
\{
??Value\
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉