目錄
簡介 一、數組 1. 靜態數組
array 2. 動態數組
2.1. vector
2.2. priority_queue
2.3. deque
2.4. stack
2.5. queue
二、單向鏈表
forward_list
三、雙向鏈表
list 四、樹
1. set
2. multiset
3. map
4. multimap 五、映射
1. unordered_set
2. unordered_multiset
3. unordered_map
4. unordered_multimap
簡介
程序員的世界里有一個經典的公式: 數據結構+算法=程序。
所以數據結構及算法的重要性就不用在此贅述了,下面直接進入正題。
在物理層面有以下五種常見的數據結構:
一、數組
1. 靜態數組
在編譯期確定數組大小,在運行期無法改變數組大小,所以稱之為靜態數組。
C++ 中的 array 由這種結構實現
int main () { array<int, 10> a = {0,1,2,3,4,5,6,7,8,9}; a[0] = 22; cout<<a.at(0)<<endl; cout<<a.back()<<endl; return 0; }
2. 動態數組
在運行期可動態改變數組大小,所以稱之為動態數組。C++ 中的動態數組有兩個,分別是 vector 和 deque。
2.1. vector
矢量,只能在末尾增刪元素
數組大小的增長策略:每次增加的長度為原來的1倍(有些編譯器增加0.5倍)。
這樣可以保證增加元素的平均時間復雜度為O(1)。
int main () { vector<int> vv = {1,2,3,4}; vv.push_back(12);// 在末尾添加元素 vv.pop_back();// 在末尾刪除元素 vv.at(3);// 讀取第三個元素 vv[3];// 讀寫第三個元素 vv.insert(vv.begin()+3, 12);// 將元素插到第三個位置上 return 0; }
2.2. priority_queue
優先隊列,默認由 vector 實現,也可由 deque 實現。它保證頂部元素始終是最大值,可用於實現堆排序。
int main () { priority_queue<int> pp; pp.push(12); pp.push(10); pp.push(11); pp.top();// 讀取頂部元素 pp.pop();// 彈出頂部元素 return 0; }
2.3. deque
雙端隊列,可以在開頭或末尾增刪元素
int main () { deque<int> dd; dd.push_front(12);// 在開頭添加元素 dd.push_back(10);// 在結尾添加元素 dd.insert(dd.begin()+1, 3);// 在位置1插入元素 dd.front();// 讀取開頭元素 dd.back();// 讀取結尾元素 dd[1]; // 讀取第一個元素 dd.pop_front();// 彈出開頭元素 dd.pop_back();// 彈出末尾元素 return 0; }
2.4. stack
棧,默認由 deque 實現,也可由 list 或 vector 實現。是一種先進后出的數據結構
int main () { stack<int> ss; ss.push(12);// 添加元素 ss.top();// 讀取棧頂元素 ss.pop();// 彈出棧頂元素 return 0; }
2.5. queue
隊列,默認由 deque實現,也可由 list 實現。是一種先進先出的數據結構
int main () { queue<int> qq; qq.push(12);// 添加元素 qq.front();// 讀取隊首元素 qq.pop();// 彈出隊首元素 return 0; }
二、單向鏈表
forward_list
只能從頭到尾順序遍歷,不能逆序遍歷,即沒有 rbegin() 接口
int main () { forward_list<int> fl; fl.push_front(12);// 在開頭添加元素 fl.insert_after(fl.begin(), 11); fl.pop_front();// 在開頭刪除元素 fl.remove(11);// 刪除元素 return 0; }
三、雙向鏈表
list
int main () { list<int> ll; ll.push_back(12);// 在末尾添加元素 ll.push_front(10);// 在開頭添加元素 ll.back();// 讀取末尾元素 ll.front();// 讀取開頭元素 ll.push_back(12); ll.unique();// 刪除重復元素 cout<<ll.size()<<endl; ll.pop_front();// 在末尾刪除元素 ll.pop_back();// 在開頭刪除元素 return 0; }
四、樹
常見的樹有二叉樹、二叉搜索樹、二叉平衡樹、紅黑樹等。
C++ 中的 set multiset map multimap 是用二叉搜索樹實現的,這種數據結構支持二分搜索,所以增刪改查的復雜度都是O(logn)。
1. set
類似數學中的集合,set 中不能包含重復的元素,元素是排好序的,且不能被修改。
int main () { set<int, less<int>> ss;// 由小到大排序 ss.insert(12); ss.insert(10); for(auto itr=ss.cbegin(); itr!=ss.cend(); itr++)cout<<*itr<<endl;// 輸出 10 12 ss.erase(ss.cbegin());// 擦除首元素 ss.count(13);// 元素 13 的個數,0 或 1 ss.find(10);// 查找元素 12,返回迭代器,若沒找到返回 ss.end() return 0; }
2. multiset
與 set 類似,但可以包含重復元素
int main () { multiset<int, less<int>> ms;// 由小到大排序 ms.insert(12); ms.insert(10); ms.insert(10); for(auto itr=ms.cbegin(); itr!=ms.cend(); itr++)cout<<*itr<<endl;// 輸出 10 10 12 cout<<""<<endl; auto pp = ms.equal_range(10); for(auto itr=pp.first; itr!=pp.second; itr++)cout<<*itr<<endl;// 輸出 10 10 ms.lower_bound(10);// = pp.first ms.upper_bound(10);// = pp.second return 0; }
3. map
元素由 (key,value) 對組成,接口與 set 類似,在插入與遍歷元素時有些區別
int main () { map<int, int> mm; mm[1] = 1;// 插入元素 (1,1) mm.insert(make_pair(2,2));// 插入元素 (2,2) for(auto itr=mm.cbegin(); itr!=mm.cend(); itr++) cout<<"("<<itr->first<<","<<itr->second<<")"<<endl;// 輸出 (1,1) (2,2) return 0; }
4. multimap
int main () { multimap<int, int> mm; mm.insert(make_pair(1,10));// 插入元素 (1,10) mm.insert(make_pair(1,11));// 插入元素 (1,11) mm.insert(make_pair(2,2));// 插入元素 (2,2) for(auto itr=mm.cbegin(); itr!=mm.cend(); itr++)// 遍歷所有元素 cout<<"("<<itr->first<<","<<itr->second<<")"<<endl;// 輸出 (1,10) (1,11) (2,2) for(auto itr=mm.lower_bound(1); itr!=mm.upper_bound(1); itr++)// 遍歷 key=1 的元素 cout<<"("<<itr->first<<","<<itr->second<<")"<<endl;// 輸出 (1,10) (1,11) mm.erase(1);// 刪除所有 key=1 的元素 mm.erase(mm.cbegin());// 刪除第一個元素 return 0; }
五、映射
映射類似數學中的函數,每一個 key 對應一個 value,寫成函數表達式為:value=f(key),其中 f 被稱為哈希函數。
C++11 中的 unordered_set unordered_multiset unordered_map unordered_multimap 是用映射實現的,這種數據結構可以在O(1)的時間復雜度下訪問單個元素,效率高於二叉搜索樹(O(logn)),但是遍歷元素的效率比二叉搜索樹低。
1. unordered_set
接口與 set 類似,不在贅述
2. unordered_multiset
接口與 multiset 類似,不在贅述
3. unordered_map
接口與 map 類似,不在贅述
4. unordered_multimap
接口與 multimap 類似,不在贅述