一、简介
Vector中所采用的数据结构非常简单:线性连续空间。当分配空间被占满而仍然需要添加元素时,vector便会进行一场空间重新配置的大工程!在这里,程序员需要注意的是,一旦引起空间重新配置,之前指向原vector的所有迭代器就都失效了,这一点在工程中容易引起bug。
List则对空间的运用有绝对的精准,一点也不浪费。注意,list内部构成的实际是一个环状的双向链表!所以只需要一个指针,便可以完整地表现整个链表。
Deque相比于vector而言,它没有容量的概念,因为deque是动态地以分段连续空间组合而成,随时都可以增加一段新的空间并链接起来。
为了使得deque在逻辑上看起来是连续空间,在STL内部实现实际是使用了一块map(不是STL中的map容器)作为主控,map是一小块连续空间,其中每个元素都是指针,指向另一段较大的连续线性空间,称为缓冲区,这些缓冲区才是真正存放deque元素的主体。
二、Vector
1、vector特点
(1)将元素置于一个动态数组中加以管理。
(2)可以随机存取元素(用索引字节存取)
(3)数组尾部添加或移除元素非常快速。当在头部或中部安插元素比较费时。
2、vector成员函数
(1)push/pop
c.push_back(elem) //在尾部插入一个elem数据。
c.pop_back() //删除末尾的数据。
【示例】
vector<int> v;
v.push_back(1);
v.pop_back();
**```
(2)assign**
```c
//将[beg,end)一个左闭右开区间的数据赋值给c。
c.assign(beg,end)
//将n个elem的拷贝赋值给c。
c.assign (n,elem)
【示例】
vector<int> v1,v2, v;
v1.push_back(10);
v1.push_back(20);
v2.push_back(30);
v2.assign(v1.begin(),v1.end());
v.assign(5, 10);
(3)begin/end/rbegin/rend/at
//传回索引为index的数据,如果index越界,抛出out_of_range异常。
c.at(int index)
//返回指向第一个数据的迭代器。
c.begin()
//返回指向最后一个数据之后的迭代器。
c.end()
//返回逆向队列的第一个数据,即c容器的最后一个数据。
c.rbegin()
//返回逆向队列的最后一个数据的下一个位置,即c容器的第一个数据再往前的一个位置。
c.rend()
【示例】
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
cout << v.at(2) << endl;
vector<int>::iterator it;
for(it = v.begin();it!=v.end();it++){
cout << *it << "\t";
}
cout << endl;
(4)clear/empty/front/back
c.clear()//移除容器中的所有数据。
c.empty()//判断容器是否为空。
c.front()//返回第一个数据。
c.back()//传回最后一个数据,不检查这个数据是否存在。
【示例】
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
if(!vec.empty()){
cout << “the first number is:” << v.front() << endl;
cout << “the last number is:” << v.back() << endl;
}
(5)insert系列
//在pos位置插入一个elem的拷贝,返回插入的值的迭代器。
c.insert(pos,elem)
//在pos位置插入n个elem的数据,无返回值。
c.insert(pos,n,elem)
//在pos位置插入在[beg,end)区间的数据,无返回值。
c.insert(pos,beg,end)
【示例】
vector<int> v;
v.insert(v.begin(),10);
v.insert(v.begin(),2,20);
v.insert(v.begin(),v1.begin(),v1.begin()+2);
(6)erase系列
//删除pos位置的数据,传回下一个数据的位置。
c.erase(pos)
//删除[beg,end)区间的数据,传回下一个数据的位置。
c.erase(beg,end)
【示例】
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.erase(v.begin());
//v.erase(v.begin(), v.end());
(7)swap
c1.swap(c2)//将c1和c2交换。
swap(c1,c2//)同上。
【示例】
vector<int> v1,v2,v3;
v1.push_back(10);
v2.swap(v1);
swap(v3,v1);
三、Deque
1、Deque特点
(1)deque是“double-ended queue的缩写
(2)可以随机存取元素(用索引直接存取)
(3)数组头部和尾部添加或移除元素都非常快,当在中部或头部安插元素比较费时。
双端队列(deque),顾名思义,两端都可以操作,插入和删除。而且,还可以在中间进行操作。内部采用线性表顺序结构,与vector不同的是,deque采用分块的线性存储结构存储数据,每块大小512字节。
所有的deque块使用一个Map块进行管理,每个Map数据项纪录各个deque块的首地址。当考虑容器内部的内存分配策略和操作性能时,deque相对于vector更有优势,同时,也可以用下标来访问。
2、构造函数
deque<Elem> c //创建一个空的deque
deque<Elem> c1(c2) //复制一个deque。
deque<Elem> c(n) //创建一个deque,含有n个数据,数据均已缺省构造产生。
deque<Elem> c(n, elem)// 创建一个含有n个elem拷贝的deque。
deque<Elem> c(beg,end) //创建一个以[beg;end)区间的deque。
~deque<Elem>() //销毁所有数据,释放内存。
3、成员函数
(1)begin_end系列
c.begin()//返回指向第一个元素的迭代器
c.end()//返回指向最后一个元素下一个位置的迭代器
c.rbegin()//返回指向反向队列的第一个元素的迭代器(即原队列的最后一个元素)
c.rend()//返回指向反向队列的最后一个元素的下一个位置(即原队列的第一个元素的前一个位置)
【示例】
deque<int> d {
1,2,3,4,5};
deque<int>::iterator it;//deque迭代器
deque<int>::reverse_iterator rit;//deque反向迭代器
for(it=d.begin();it!=d.end();it++){
cout << *it << " ";
}
cout << endl;
for(rit=d.rbegin(); rit!=d.rend(); rit++){
cout << *rit << " ";
}
cout << endl;
(2)assign系列
c.assign(n,num)将n个num拷贝复制到容器c
c.assign(beg,end)将[beg,end)区间的数据拷贝复制到容器c
【示例】
deque<int> d1 {
1,2,3,4,5},d2;
d2.assign(2, 8);
deque<int>::iterator it;
cout << "d2.assign(n,num):";
for(it=d2.begin();it!=d2.end();it++){
cout << *it << " ";
}
d2.assign(d1.begin