一、順序容器類型
順序容器 |
vector |
支持快速隨機訪問 |
list |
支持快速插入、刪除 |
deque |
雙端隊列 |
順序容器適配器 |
stack |
後進先出(LIFO)棧 |
queue |
先進先出(FIFO)隊列 |
priority_queue |
有優先級管理的隊列 |
二、順序容器的定義
1、創建和初始化一個順序容器對象
vector<int> ivec(10); //ivec包含10個值爲0的int
(默認構造函數初始化)
vector<int> ivec(10,1); //ivec包含10個值爲1的int
(相應構造函數)
vector<int> ivec1(10,1);
vector<int> ivec2(ivec1); //拷貝ivec1的內容(ivec1、ivec2 容器類型必須相同)
vector<int> ivec1(10,1);
vector<int>::iterator mid = ivec1.begin() + ivec2.size()/2;
list<int> ivec2(mid,ivec1.end()); //ivec2初始化爲ivec1中的指定元素 (容器類型可以不同,容器元素類型需要兼容)
int array[] = {1,2,3,4,5};
vector<int> ivec(array,array + 5); //也可以用指針初始化容器
2、定義一個容器,其元素類型爲容器類型
必須用空格分割兩個相鄰的剪頭符號,以與>>、<<操作符卻別。
vector< vector<int> > lines;
三、迭代器和迭代器範圍
1、迭代器運算
常用的迭代器運算:解引用(*iter)、剪頭操作(iter->men)、自增自減(++iter,--iter,iter++,iter--)、比較(iter1 == iter2,iter1 != iter2)
vector、deque支持對元素的快速、隨機訪問,所以它們還支持一下運算:
加減(iter + n,iter - n,iter1 - iter2)、關係運算(iter1 > iter2 ,iter1 <= iter2 )
2、迭代器範圍
左閉右合區間:[beg,end)
四、順序容器的操作
1、容器定義的類型別名
size_type |
容器長度,無符號整型 |
iterator |
迭代器 |
const_iterator |
元素爲只讀類型容器的迭代器 |
reverse_iterator |
按逆序尋址元素的迭代器 |
const_reverse_iterator |
元素爲只讀類型容器的逆序尋址迭代器 |
difference_type |
迭代器差值,可爲負 |
value_type |
元素類型 |
reference |
元素的引用類型 |
const_reference |
容器元素爲常量,其元素的引用類型 |
2、begin、end成員
c.begin() |
返回一個迭代器,指向容器的第一個元素 |
c.end() |
返回一個迭代器,指向容器第一個元素的下一個位置 |
c.rbegin() |
返回一個逆序迭代器,指向容器的最後一個元素 |
c.rend() |
返回一個逆序迭代器,指向容器第一個元素的前一個位置 |
3、添加元素
c.push_back(t) |
在容器尾部添加元素 |
c.push_front(t) |
在容器前端添加元素 |
list、deque |
c.insert(p,t) |
在p指向元素前插入元素,返回指向新元素的迭代器 |
c.insert(p,n,t) |
在p指向元素前添加n個元素 |
c.insert(p,b,e) |
在p指向元素前插入迭代器b、e標記範圍內的元素(左閉右開區間) |
4、容器大小操作
c.size() |
返回容器中元素的個數,類型爲c::size_type |
c.max_size() |
返回容器中最多可容納的元素個數,類型爲c::size_type |
c.empty() |
判斷是否爲空 |
c.resize(n) |
調整c的大小爲n |
c.reszie(n,t) |
調整c的大小爲n,並初始化元素 |
resize操作使之前的迭代器失效。
5、元素訪問
c.back() |
返回最後一個元素的引用,c爲空則該操作未定義 |
c.front() |
返回第一個元素的引用,c爲空則該操作未定義 |
vector、deque |
c[n] |
返回下邊爲n元素的引用,若n<0或n>=c.size(),則該操作未定義 |
c.at(n) |
返回下標爲n元素的引用,若n<0或n>=c.size(),則拋出out_of_range異常 |
int a[] = {1,2,3,4,5};
list<int> mylist(a,a + 5);
if(!mylist.empty()) //先判斷容器是否爲空
{
list<int>::reference beg1 = *mylist.begin();
list<int>::reference beg2 = mylist.front();
list<int>::reference end1 = *(--mylist.end()); //mylist.end()返回的迭代器指向最後一個元素下一位置
list<int>::reference end2 = mylist.back();
}
6、刪除元素
c.erase(p) |
刪除迭代器p所指向的元素,返回指向所刪除元素下一位置的迭代器;
若p指向容器最後一個元素下一位置,則返回迭代器也指向此位置 |
c.erase(b,e) |
刪除迭代器b,e所標記範圍內的元素(左閉右開區間),返回指向被刪除元素段下一位置的迭代器;
若e指向容器最後一個元素下一位置,則返回迭代器也指向此位置 |
c.pop_back() |
刪除c的最後一個元素,若c爲空則未定義 |
c.pop_front() |
刪除c的第一個元素,若c爲空則未定義 |
//刪除mylist中指定元素
int a[] = {1,2,3,4,5};
list<int> mylist(a,a + 5);
list<int>::iterator iter = find(mylist.begin(),mylist.end(),3);
if(iter != mylist.end()) //判斷是否存在指定元素
mylist.erase(iter);
7、賦值與swap
c1 = c2 |
刪除c1中元素,賦值c2中元素到c1(容器類型和元素類型相同) |
c1.swap(c2) |
交換c1、c2中的內容(迭代器不會失效) |
c.assign(b,e) |
將迭代器b,e範圍內的值複製到c(b,e不能指向c) |
c.assign(n,t) |
c的內容設置爲n個t |
char* p1 = "Hello";
char* p2 = "World";
list<char*> mylist;
mylist.push_back(p1);
mylist.push_back(p2);
vector<string> myvector;
myvector.assign(mylist.begin(),mylist.end()); //元素類型不同,但可相互兼容,使用assgin
五、vector容器自增長
vector.size()獲得容器的當前元素個數;vector.capacity()獲得容器的容量;vector.reservce()設置容器容量。
#include <iostream>
#include <vector>
using namespace std;
vector<int> myvector;
void display()
{
cout<<"**********************"<<endl;
cout<<"size:"<<myvector.size()<<endl;
cout<<"capacity:"<<myvector.capacity()<<endl;
}
int main()
{
display();
for (int i = 0; i != 24; i++)
{
myvector.push_back(i);
}
display();
myvector.reserve(50);
myvector.clear();
for (int i = 0; i != 50; i++)
{
myvector.push_back(i);
}
display();
myvector.push_back(100);
display();
return 0;
}
運行結果:
設置容器容量後,當容器元素超過容器容量,容器容量以一定規律增加,如capacity的1倍或1/2倍。
六、各種容器的優點
容器 |
插入、刪除操作 |
元素訪問 |
vector |
容器末尾insert、erase快,其它位置開銷大 |
任意位置快速訪問 |
list |
容器任何位置insert、erase快 |
只提供元素的順序訪問 |
deque |
容器首部、尾部insert、erase快,其它位置開銷大 |
任意位置快速訪問 |