一、vector简介
1、 vector是表示可变大小数组的序列容器
2、vector和数组一样采用连续空间存储数据,可用下标对其进行访问,效率很高。不同的是其大小可以动态改变是由容器自动处理的。
3、vector插入一个数据,需要重新分配一个数组,并将所有元素移到这个数组。
4、与其他容器相比,vector访问元素、末尾添加和删除元素效率更高效,不在末尾的添加和删除元素操作效率更低。
二、vector的常用接口
1、构造函数
(1)vector():无参构造
(2)vector(size_type n, const value_type& val = value_type()):构造并初始化n个val
(3)vector(const vector& x):拷贝构造
(4)vector(iterator first,iterator last):利用迭代器进行构造
2、迭代器 iterator
vector<int>a(8,6); vector<int>::iterator it=v.begin(); vector<int>::const_iterator it =v.cbegin();
(1)begin():第一个数据位置的iterator
(2)end():最后一个数据的下一个位置
(3)rbegin():最后一个数据位置的iterator
(4)rend():第一个数据的前一个位置
(5)cbegin():第一个数据位置的const_iterator
(6)cend():最后一个数据的下一个位置const_iterator
3、空间增长
(1)capacity
运行结果:capacity在vs下大概为1.5倍增长,g++下为2倍增长。
其中1.5倍增容其效率更低,而2倍增容效率更高但是浪费空间更多。
(2)reserve:开辟空间,若知道用多少空间可以用reserve减小vector增容缺陷。
结果对比:
没有reserve:
有reserve:
(3)resize和size:开空间同时还会进行初始化,影响size
结果:
4、增删修改
//增删修改
//push_back(i) 尾插
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
for (auto &i : v)
{
cout << i;
}
cout << endl;
//pop_back() 尾删
v.pop_back();
v.pop_back();
for (auto &i : v)
{
cout << i;
}
cout << endl;
//insert 在pos位置之前插入
v.insert(v.begin()+1, 6);
for (auto &i : v)
{
cout << i;
}
cout << endl;
//erase 删除pos位置的数据
v.erase(v.begin() + 1);
for (auto &i : v)
{
cout << i;
}
cout << endl;
vector<int>s(6, 0);
//swap 交换两个vector空间
s.swap(v);
//中括号下标访问元素
for (int i = 0; i < s.size(); i++)
{
cout << s[i];
}
cout << endl;
运行结果:
(1)尾插:void push_back (const value_type& val);
``
(2)尾删:void pop_back();
(3)insert在position位置(pos位置由迭代器给出)插入val:
iterator insert (iterator position constvalue_type& val);
void insert (iterator position, size_type n, const value_type& val);
template
void insert (iterator position, InputIterator first, InputIterator last);(4)删除position位置的数据:iterator erase (iterator position); //删除单个位置
iterator erase(iterator first, iterator last);//删除一段
(5)交换两个vector的数据空间:void swap (vector& x);
(6)像数组一样访问:reference
operator[] (size_type n);
(7)查找:InputIterator find (InputIterator first, InputIteratorlast, const T& val); find函数用法举例:
三、迭代器失效问题
1、删除pos位置的数据会导致迭代器失效
2、在pos位置insert插入数据 ,迭代器失效。(因为insert可能导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了)
//迭代器失效
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
vector<int>::iterator pos = find(v.begin(), v.end(), 6);
//1、删除pos位置数据,迭代器失效
v.erase(pos);
//cout << *pos << endl;//非法访问
for (auto &i : v)
{
cout << i << endl;
}
//2、insert会导致增容,增容后pos还指向原来的空间
//可是原空间已经释放了,会导致迭代器失效
pos = find(v.begin(), v.end(), 1);
v.insert(pos, 30);
cout << *pos << endl;//非法访问
3、解决erase的迭代器失效问题举例
四、vector的深层理解
1、实现是基于模板类
2、迭代器和string一样都是原生指针
3、扩容
4、memcpy可以实现结构体的深拷贝,但是只能实现类的浅拷贝。
void *memcpy(void *dest, const void *src, size_t n);
( 从src的开始位置拷贝n个字节的数据到dest。如果dest存在数据,将会被覆盖。memcpy函数的返回值是dest的指针。memcpy函数定义在string.h头文件里。)5、memset:
(1)memset()函数原型是:
void *memset(void *buffer, int c, int count)
buffer:为指针或是数组,
c:是赋给buffer的值,
count:是buffer的长度.
(2)memset按照字节进行操作: