Ref: STL中map的數據結構html
C++ STL中標準關聯容器set, multiset, map, multimap內部採用的就是一種很是高效的平衡檢索二叉樹:紅黑樹,也成爲RB樹(Red-Black Tree)。RB樹的統計性能要好於通常的平衡二叉樹(有些書籍根據做者姓名,Adelson-Velskii和Landis,將其稱爲AVL-樹),因此被STL選擇做爲了關聯容器的內部結構。本文並不會介紹詳細AVL樹和RB樹的實現以及他們的優劣,關於RB樹的詳細實現參看紅黑樹: 理論與實現(理論篇)。本文針對開始提出的幾個問題的回答,來向你們簡單介紹map和set的底層數據結構。c++
相似list高效;所以插入的時候只須要稍作變換,把節點的指針指向新的節點就能夠了。刪除的時候相似,稍作變換後把指向刪除節點的指針指向其餘節點就OK了數據結構
內存沒有變,指向內存的指針怎麼會失效呢。app
使用reserv() 函數預分配函數
假定你想創建一個容納1-1000值的vector。沒有使用reserve,你能夠像這樣來作:post
vector<int> v;
for (int i = 1; i <= 1000; ++i) v.push_back(i);
在大多數STL實現中,這段代碼在循環過程當中將會致使2到10次從新分配。性能
使用reserve:ui
vector<int> v; v.reserve(1000);
for (int i = 1; i <= 1000; ++i) v.push_back(i);
Thus, 這在循環中不會發生從新分配。
this
這涉及到二叉樹的性質,便容易理解了。url
前幾天以爲STL中沒有樹和圖真是一種莫大的遺憾啊,可是在網上搜了搜,發現其實能夠用容器很簡單的構造樹。
There are two reasons you could want to use a tree:
You want to mirror the problem using a tree-like structure:
For this, we have boost graph library
Or you want a container that has tree like access characteristics For this we have
std::map
(and std::multimap
)std::set
(and std::multiset
)Basically, the characteristics of these two containers are such that they practically have to be implemented using trees (though this is not actually a requirement).
See also this question: C tree Implementation
Ref: boost graph library
Algorithms
The BGL algorithms consist of a core set of algorithm patterns (implemented as generic algorithms) and a larger set of graph algorithms. The core algorithm patterns are
By themselves, the algorithm patterns do not compute any meaningful quantities over graphs; they are merely building blocks for constructing graph algorithms. The graph algorithms in the BGL currently include
Boost 做爲「準標準庫」,其中包括了二十個分類,上述的graph屬於其中的一個。
Ref: 二叉樹總結(一)概念和性質
二叉樹的性質
滿二叉樹:深度爲k且具備2^k-1個結點的二叉樹。即滿二叉樹中的每一層上的結點數都是最大的結點數。
徹底二叉樹:深度爲k具備n個結點的二叉樹,當且僅當每個結點與深度爲k的滿二叉樹中的編號從1至n的結點一一對應。
證實:下面用"數學概括法"進行證實。
(01) 當i=1時,第i層的節點數目爲2{i-1}=2{0}=1。由於第1層上只有一個根結點,因此命題成立。
(02) 假設當i>1,第i層的節點數目爲2{i-1}。這個是根據(01)推斷出來的!
下面根據這個假設,推斷出"第(i+1)層的節點數目爲2{i}"便可。
因爲二叉樹的每一個結點至多有兩個孩子,故"第(i+1)層上的結點數目" 最可能是 "第i層的結點數目的2倍"。即,第(i+1)層上的結點數目最大值=2×2{i-1}=2{i}。
故假設成立,原命題得證!
證實:在具備相同深度的二叉樹中,當每一層都含有最大結點數時,其樹中結點數最多。利用"性質1"可知,深度爲k的二叉樹的結點數至多爲:
20+21+…+2k-1=2k-1
故原命題得證!
證實:根據"性質2"可知,高度爲h的二叉樹最多有2{h}–1個結點。反之,對於包含n個節點的二叉樹的高度至少爲log2(n+1)。
證實:由於二叉樹中全部結點的度數均不大於2,因此結點總數(記爲n)="0度結點數(n0)" + "1度結點數(n1)" + "2度結點數(n2)"。由此,獲得等式一。
(等式一) n=n0+n1+n2
另外一方面,0度結點沒有孩子,1度結點有一個孩子,2度結點有兩個孩子,故二叉樹中孩子結點總數是:n1+2n2。此外,只有根不是任何結點的孩子。故二叉樹中的結點總數又可表示爲等式二。
(等式二) n=n1+2n2+1
由(等式一)和(等式二)計算獲得:n0=n2+1。原命題得證!
Ref: 二叉樹總結(二)樹的遍歷
經過層次遍歷構造二叉樹。
詳見:[c++] Associative Containers
End.