STL 就是所謂的標準模板庫(Standard Template Library),這可能是C++程序員的一大利器。
總的來說,STL包括幾個部分:容器,算法(泛型算法),迭代器三個主要部分(當然還包含仿函數,適配器等其他部分),下圖說明了三個主要部分之間的關系(網圖,侵刪)。
要是詳細的總結,這肯定是一本類似于《C++ Primer》的大書。本篇文章主要是對于STL中的常用容器的底層數據結構進行總結整理。
I、vector
1.1 vector底層數據結構
vector是我們用到最多的數據結構,其底層數據結構是數組,由于數組的特點,vector也具有以下特性:
1、O(1)時間的快速訪問;
2、順序存儲,所以插入到非尾結點位置所需時間復雜度為O(n),刪除也一樣;
3、擴容規則:
當我們新建一個vector的時候,會首先分配給他一片連續的內存空間,如std::vector<int> vec
,當通過push_back向其中增加元素時,如果初始分配空間已滿,就會引起vector擴容,其擴容規則在gcc下以2倍方式完成:
首先重新申請一個2倍大的內存空間;
然后將原空間的內容拷貝過來;
最后將原空間內容進行釋放,將內存交還給操作系統;
測試代碼如下:
#include<iostream>
#include<vector>
using namespace std;
void mycapacity(const vector<int>& vec)
{
cout << "分配總空間大小為:" << vec.capacity() << endl;
}
void mysize(const vector<int>& vec)
{
cout << "已用空間大小為:" << vec.size() << endl;
}
void myprint(const vector<int>& vec)
{
for (int i = 0; i < vec.size(); ++i)
cout << vec[i] << ",";
cout << endl;
}
int main()
{
vector<int> vec;
cout << "起始狀態:" << endl;
mycapacity(vec);
mysize(vec);
cout << "========================" << endl;
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
cout << "壓入第" << i+1 << "個元素之后:" << endl;
myprint(vec);
mycapacity(vec);
mysize(vec);
cout << "========================" << endl;
}
return 0;
}
從輸出結果中的三個紅色箭頭可以看出vector的擴容規則。
4、注意事項:
根據vector的插入和刪除特性,以及擴容規則,我們在使用vector的時候要注意,在插入位置和刪除位置之后的所有迭代器和指針引用都會失效,同理,擴容之后的所有迭代器指針和引用也都會失效。
II、map & multimap & unordered_map & unordered_multimap
2.1 map與multimap底層數據結構
map與multimap是STL中的關聯容器、提供一對一key-value的數據處理能力; map與multimap的區別在于,multimap允許關鍵字重復,而map不允許重復。
這兩個關聯容器的底層數據結構均為紅黑樹,關于紅黑樹的理解可以參考教你透徹了解紅黑樹一文。
根據紅黑樹的原理,map與multimap可以實現O(lgn)的查找,插入和刪除。
2.2 unordered_map 與unordered_multimap底層數據結構
unordered_map與unordered_multimap 對比2.1中的兩種map在于其2.1中的兩個容器實現了以key為序排列,也就是說map與multimap為有序的。
而unordered_map與unordered_multimap中key為無序排列,其底層實現為hash table,因此其查找時間復雜度理論上達到了O(n),之所以說理論上是因為在理想無碰撞的情況下,而真實情況未必如此。
III、set & multiset & unordered_set & unordered_multiset
以上四種容器也都是關聯容器,set系與map系的區別在于map中存儲的是<key-value>,而set可以理解為關鍵字即值,即只保存關鍵字的容器。
3.1 set & multiset底層數據結構
set與multiset有序存儲元素,這兩種容器的底層實現與map一樣都是紅黑樹,所以能實現O(lgn)的查找,插入,刪除操作。
set與multiset的區別在于是否允許重復;
3.2 unordered_set & unordered_multiset
與unordered_map & unordered_multimap相同,其底層實現為hash table;
IV、 priority_queue
4.1 priority_queue
優先級隊列相當于一個有權值的單向隊列queue,在這個隊列中,所有元素是按照優先級排列的。
priority_queue根據堆的處理規則來調整元素之間的位置,關于堆的原理,可以參考堆;
根據堆的特性,優先級隊列實現了取出最大最小元素時間復雜度為O(1),對于插入和刪除,其最壞情況為O(lgn)。
V、 其他數據結構
list的底層數據結構為雙向鏈表,特點是支持快速的增刪。
queue為單向隊列,為先入先出原則。
deque為雙向隊列,其對比queue可以實現在頭尾兩端高效的插入和刪除操作。
歡迎轉載,轉載請注明出處wenmingxing 你好呀 C++