一、容器
概念:容器是儲存其他對象的對象。被儲存的對象必須是同一類型。
基本特征:以下用X表示容器類型(后面會講到),T表示儲存的對象類型(如int);a和b表示為類型X的值;u表示為一個X容器的標識符(如果X表示vector<int>,則u是一個vector<int>對象。)
表 達 式 |
返 回 類 型 |
說 明 |
復 雜 度 |
X::iterator |
指向T的迭代器類型 |
滿足正向迭代器要求的任何迭代器 |
編譯時間 |
X u |
|
創建一個名為u的空容器 |
固定 |
X () |
|
創建一個匿名空容器 |
固定 |
X u(a) |
|
同X u(a); |
線性 |
a.begin() |
迭代器 |
返回指向容器第一個元素的迭代器 |
固定 |
a.end() |
迭代器 |
返回指向超尾值的迭代器 |
固定 |
a.size() |
無符號整型 |
返回元素個數 |
固定 |
a.swap() |
void |
交換a和b內容 |
固定 |
a == b |
可轉換為bool |
如果a和b長度相當且每個元素都相等,則為真 |
線性 |
a != b |
可轉換為bool |
返回!(a == b) |
線性 |
二、序列容器
常用容器:vector、deque、list、queue、stack
概念:序列是對基本容器的一種改進,在保持其基礎功能上增加一些我們需要的更為方便的功能。
要求:序列的元素必須是嚴格的線性順序排序。因此序列中的元素具有確定的順序,可以執行將值插入到特定位置、刪除特定區間等操作。
序列容器基本特征:以下用t表示類型為T(儲存在容器中的值的類型)的值,n表示整數,p、q、i和j表示迭代器。
表 達 式 |
返 回 類 型 |
說 明 |
X a(n,t) |
|
聲明一個名為a的由n個t值組成的序列 |
X(n,t) |
|
創建一個由n個t值組成的匿名序列 |
X a(i,j) |
|
聲明一個名為a的序列,並將其初始化為區間[i,j)的內容 |
X(i,j) |
|
創建一個匿名序列,並將其初始化為區間[i,j)的內容 |
a.insert(p,t) |
迭代器 |
將t插入到p的前面 |
a.insert(p,n,t) |
void |
將n個t插入到p的前面 |
a.insert(p,i,j) |
void |
將區間[i,j)的元素插入到p前面 |
a.erase(p) |
迭代器 |
刪除p所指向的元素 |
a.erase(p,q) |
迭代器 |
刪除區間[p,q)中的元素 |
a.clear() |
void |
清空容器 |
不同容器特有的特征:
表 達 式 |
返 回 類 型 |
含 義 |
支 持 的 容 器 |
a.front() |
|
|
vector、list、deque |
a.back() |
|
|
vector、list、deque |
a.push_front(t) |
|
|
list、deque |
a.push_back(t) |
|
|
vector、list、deque |
a.pop_front(t) |
|
|
list、deque |
a.pop_back(t) |
|
|
vector、list、deque |
a[n] |
|
|
vector、deque |
a.at(t) |
|
|
vector、deque |
*a[n]和a.at(n)都返回一個指向容器中第n個元素的引用。區別在於:如果n落在容器有效區間之外,a.at(n)將執行邊界檢查,並引發out_of_range異常。
*之所以vector沒有push_front(),是因為vector執行此表達式復雜度為線性時間,而deque為固定時間。(這與它們的特性有關,下面講到)
(一)vector
- vector是最簡單也是最重要的一個容器。其頭文件為<vector>.
- vector是數組的一種類表示,它有以下優點:自動管理內存、動態改變長度並隨着元素的增減而增大或縮小。
- 在尾部添加元素是固定時間,在頭部或中間添加或刪除元素是線性時間。
- vector是可反轉容器。下面以vector為例介紹可反轉容器。
(待補充)
(二)deque
- 頭文件<deque>
- 在STL中deque類似vector,並且支持隨機訪問。區別在於:從deque起始位置插入刪除元素時間是固定的。
- 為了實現在deque倆段執行插入和刪除操作的時間為固定這一目的,deque對象設計比vector設計更為復雜一些。因此,在序列中部執行插入刪除操作時,vector更快一些。
(三)list
- list表示雙向鏈表。頭文件<list>
- list為可反轉容器。
- list不支持數組表示法和隨機訪問。
- 與矢量迭代器不同,從容器中插入或刪除元素之后,鏈表迭代器指向的元素不變。這與鏈表的特性有關,刪除鏈表中的元素並不改變其它元素位置,只是修改鏈接信息。(代碼證明)
- 不同於vector,list不強調隨機訪問與快速訪問,list強調的是元素的快速插入與刪除
- 再次提醒:序列容器都是線性排序,因此list首尾不會相連。
- list成員函數:
函 數 |
說 明 |
void merge(list<T,Alloc>& x) |
將鏈表x與調用鏈表合並,倆個鏈表必須已排序。合並后的經過排序的鏈表保存在調用鏈表中,x為空。線性時間。 |
void remove(const T & val) |
從鏈表中刪除val的所有實例。線性時間。 |
void sort() |
使用<運算符對鏈表進行排序,復雜度NlogN |
void splice(iterator pos,list<T,Alloc>x) |
將鏈表x的類容插入到pos前面,x將為空。固定時間。 |
void unique() |
將連續相同的元素壓縮為單個元素。線性時間。 |
放入代碼中:
#include<iostream>
#include<list>
#include<iterator>
#include<algorithm>
using namespace std;
void outint(int n){cout << n << " ";}
void Show(list<int> dice,int flag){
if(flag) cout<<"dice = ";
else cout<< " two = ";
for_each(dice.begin(),dice.end(),outint);//輸出容器的元素。
cout << endl;
}//此函數用來輸出容器元素
int main()
{
list<int> dice(5,2);//一種賦初值方法。5個2
Show(dice,1);
int a[] = {1,5,4,3};
dice.insert(dice.begin(),a,a+4);//insert函數用法
Show(dice,1);
list<int> two(dice);//另一種賦初值方法,其值與dice相等
Show(two,0);
dice.splice(dice.begin(),two);//splice函數用法
Show(dice,1);
Show(two,0); //two清空
two = dice;
dice.unique();//unique壓縮連續相同的元素
Show(dice,1);
dice.sort();//sort函數用法
two.sort();
Show(dice,1);
Show(two,0);
dice.merge(two);//merge函數用法,將two合並到dice中,two將為空。
Show(dice,1);
Show(two,0);
dice.remove(2);//移除所有2
Show(dice,1);
return 0;
}
insert()與splice()之間的不同主要在與:insert()將原始區間的副本插入到目標地址,而splice()則將原始區間移到目標地址。splice()執行后,迭代器仍有效。也就是說原本指向two中一個元素的迭代器,在使用過splice后仍然指向它。
remove()函數還有更加方便的拓展,將在以后講到。
(四)queue
- 頭文件<queue>
- queue不允許隨機訪問隊列元素,不允許遍歷隊列,可以進行隊列基本操作
- 可以將元素添加到隊尾,從隊首刪除元素,查看隊尾和隊首的值,檢查元素數目和測試隊列是否為空
-
queue的操作:
方 法 說 明 bool empty()const 如果隊列為空,則返回true,否則返回false size_type size()const 返回隊列中元素的數目 T& front() 返回指向隊首元素的引用 T& back() 返回指向隊尾元素的引用 void push(const T& x) 在隊尾插入x void pop() 刪除隊首元素
(五)stack
- 頭文件<stack>
- stack是一個適配器,它給底層類(默認vector)提供典型棧接口。
- stack不允許隨機訪問棧元素,不允許遍歷棧,把使用限制在定義棧的基本操作上
- 可以將值壓入棧頂,從棧頂彈出元素,查看棧頂的值,檢查元素數目,測試棧是否為空
- stack的操作:
-
方 法 說 明 bool empty()const 如果棧為空,返回true,否則返回false size_type size()const 返回棧中元素數目 T& top() 返回指向棧頂元素的引用 void push(const T& x) 在棧頂插入x void pop() 刪除棧頂元素 與queue類似,如果要使用棧中的值,必須首先使用top()來檢索這個值,然后使用pop()將它從棧頂刪除。
序列容器還有forword_list(C++11)、priority_queue、array,有興趣的可以去看一看,但我覺的用的不太常用,不打算整理出來了。
三、關聯容器
內容太多了,為了美觀以及方便查看不得不另起一篇。