來源:blog.csdn.net/qq_15371293/article/details/117090780 項目場景: ClickHouse 操作基於 Mybatis-puls源碼擴展開發。解決ClickHouse的修改和刪除 SQL操作與Mysql不相同。 基於 Mybatis-puls: up ...
STL這部分推薦直接看《C++ primer》的9到11章內容,有非常詳細的介面列表,還有很多例子。附錄里還有常用的泛型演算法,適合經常看一下
vector容器
底層數據結構:動態開闢的數組,每次以原來空間大小的2倍進行擴容的
vector<int> vec;
deque雙端隊列和list鏈表
初始的元素放在隊列的中間,方便後續添加元素。外部有一個mapper保存隊列,隊滿的時候會對mapper擴容,隊列放在擴容後的mapper的sizeof(原來mapper)/2的位置。
deque容器:
list容器:
vector、deque、list對比
vecotr和deque之間的區別?
- deque底層記憶體是否是連續的? 不是。deque是由一個二維數組構成的。每一個第二維是連續的,第一維數據不是連續的。
- 前中後插入刪除的時間複雜度:中間和末尾是O(1),前面插入deque是O(1),vector是O(n)
- 對於記憶體的使用效率: vector的低,需要的記憶體空間必須是連續的。deque可以分塊進行存儲,不需要記憶體空間必須是連續的。
- 由於deque的第二維記憶體空間不是連續的,所以在deuqe中間進行元素的insert或者erase,造成元素移動的時候臂vector要慢
vector和list之間的區別?
- list底層是雙向迴圈鏈表
- list的增加刪除是O(1),vector增加刪除是O(n)
詳解容器適配器
無序關聯容器
unordered_set:
unordered_map:
map的operator[]重載有兩個功能:一是查詢,二如果key不存在,會插入一對數據
unordered_map<int,string> mp1;
mp1.insert(make_pair(12,"asf"));//生成pair類型
mp1.insert({123,"asfsaf"});
有序關聯容器
底層是紅黑樹結構。
自定義類型如何在有序容器中排序:要在自定義類型中提供小於運算符的重載
容器的迭代器
函數對象
函數對象就是C語言里的函數指針
把有operator()小括弧運算符重載函數的對象,稱作函數對象或者稱作仿函數。
好處:
- 通過函數對象調用operator(),可以省略函數的調用開銷,比通過函數指針調用函數(不能夠inline內聯調用)效率高。
- 因為函數對象使用類生成的,所以可以添加相關的成員變數,用來記錄函數對象使用時的更多的信息。
template<typename T>
bool mygreater(T a, T b) {
return a > b;
}
template<typename T>
bool myless(T a, T b) {
return a < b;
}
template<typename T>
class Myless{//函數對象
public:
bool operator()(T a,T b){
return a<b;
}
};
template<typename T, typename Compare>
bool compare(T a, T b, Compare comp) {//使用函數指針或者函數對象調用前面定義的兩個函數
return comp(a, b);//在使用函數指針的時候無法聲明為inline函數,效率低
}
int main() {
cout << compare(10, 30, mygreater<int>)<<endl;
cout<<compare(20,10,Myless<int>())<<endl;
return 0;
}
函數對象的一些其他用法:用於priority_queue和set:
priority_queue<int,vector<int>,Mygreater<int>> queue1;
priority_queue<int> queue2;
for(int i=0;i<20;i++){
queue1.push(rand()%100);
queue2.push(rand()%100);
}
for(int i=0;i<20;i++){
cout<<queue1.top()<<" ";
queue1.pop();
}
cout<<endl;
for(int i=0;i<20;i++){
cout<<queue2.top()<<" ";
queue2.pop();
}
cout<<endl;
/* 輸出結果:
2 5 18 21 27 34 35 41 47 61 62 67 69 69 71 78 81 91 92 95
99 95 94 91 82 67 64 58 53 45 42 38 36 27 26 24 16 12 4 0*/
//set:
set<int> set1;
set<int,Mygreater<int>> set2;
for(int i=0;i<20;i++){
set1.insert(rand()%100);
set2.insert(rand()%100);
}
for(int a:set1){
cout<<a<<" ";
}
cout<<endl;
for(int a:set2){
cout<<a<<" ";
}
cout<<endl;
/* 輸出結果
3 6 16 22 23 29 37 40 41 46 47 53 62 64 70 73 88 90 93
78 68 64 59 57 50 48 44 42 41 35 33 29 11 6 5 1*/