顺序容器是拥有单一类型元素组成的一个有序集合。主要的顺序容器有vector和list。其实还有deque(双端队列)
1.vector数据结构
使用头文件:#include <vector>
vector和数组类似,拥有一段连续的内存空间,并且起始地址不变。
因此能高效的进行随机存取,时间复杂度为o(1);
但因为内存空间是连续的,所以在进行插入和删除操作时,会造成内存块的拷贝,时间复杂度为o(n)。
另外,当数组中内存空间不够时,会重新申请一块内存空间并进行内存拷贝。
使用vector需要注意以下几点:
①如果你要表示的向量长度较长(需要为向量内部保存很多数),容易导致内存泄漏,而且效率会很低;
②Vector作为函数的参数或者返回值时,需要注意它的写法:
double Distance(vector<int>&a, vector<int>&b) 其中的“&”绝对不能少!!!
2.list数据结构
使用头文件:#include <list>
list是由双向链表实现的,因此内存空间是不连续的。
只能通过指针访问数据,所以list的随机存取非常没有效率,时间复杂度为o(n);
但由于链表的特点,能高效地进行插入和删除。
总之,如果需要高效的随机存取,而不在乎插入和删除的效率,使用vector;
如果需要大量的插入和删除,而不关心随机存取,则应使用list。
3.vector基本操作
(1)头文件:#include<vector>
(2)建立一个vector:vector<int> vec;
(3)在尾部插入元素:
vec.push_back(1);
vec.push_back(2); //把1和2压入vector,这样vec[0]就是1,vec[1]就是2
(4)插入元素:vec.insert(vec.begin()+i,a); //在第i+1个元素前面插入a;
(5)删除元素:
vec.erase(vec.begin()+2); //删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j); //删除区间[i,j-1];区间从0开始
(6)向量大小:vec.size();
(7)清空:vec.clear();
(8)使用迭代器访问元素:
vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;
(9)定义一个二维数组:
vector<vector<Point2f> > points;
points[0].size(); //指第一行的列数
4.vector如何自己增长?
容器的容量和长度:只有连续存储的容器才有容量的概念,例如vector,deque或string。list不要求容量。
为了提高效率 实际上 vector 并不是随每一个元素的插入而增长自己 而是当 vector 需要增长自身时 它实际分配的空间比当前所需的空间要多一些 也就是说 它分配了一些额外的内存容量 或者说它预留了这些存储区。
可以调用capacity()来查看当前容器的容量,调用size()来查看当前容器拥有元素的个数。
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector< int > ivec;
cout << "ivec: size: " << ivec.size()
<< " capacity: " << ivec.capacity() << endl;
for ( int ix = 0; ix < 24; ++ix )
{
ivec.push_back( ix );
cout << "ivec: size: " << ivec.size()
<< " capacity: " << ivec.capacity() << endl;
}
return 0;
}
可以看到,在ivec定义之后,长度和容量都是0。但是在插入元素之后,它的容量随每次重分配而加倍。