目录
vector的介绍
vector的使用
vector的定义
构造函数构造
拷贝构造函数构造
迭代器构造
vector的空间增长
size和capacity
resize和reserve
empty
vector的迭代器
begin和end
rbegin和rend
vector的增删查改
push_back和pop_back
insert和erase
find和swap
vector的元素访问
[]+下标
at
范围for
迭代器
迭代器失效的讨论
insert引起的迭代器失效
erase引起的迭代器失效
- vector是表示可变大小数组的序列容器.
- vector就像数组一样,也采用连续存储空间来存储元素,也就意味着可以采用下标堆vector的元素进行访问.和数组一样,但是又不数组,他的大小是可以动态改变的而且他的大小会被容器自动处理.
- vector的本质使用动态分配数组来存储他的元素,当新的元素插入时,这个数组需要被重新分配大小.
- vector的空间分配策略:vector会分配一些额外的空间可以适应可能的增长,因为存储空间比实际需要的存储空间更大,不同的库采用不同的策略权衡空间的使用和分配.但是无论和分配,重新分配的都应该时对数组增长的间隔大小,以至于在尾插的时候实在常数的时间复杂度内完成的.
- 用于vector采取连续的空间来存储元素,与其他容器相比,vector在访问元素时更加高效,
vector first;//构造一个空的int类型容器
vector second(4, 100);//构造四个值为100的int类型容器
vector fourth(third);//使用拷贝构造构造一个值和third一样的int类型的容器
vector third(second.begin(), second.end());//使用迭代器构造int的类型的容器
size是获取当前容器中有效元素的个数,capacity是获取当前容器的最大容量
vector v(10, 0);
cout << v.size() << endl;//10 获取当前容器的有效元素的个数
cout << v.capacity() << endl;//10 获取当前容器的最大容量
resize是改变容器中有效元素的个数,reserve是改变容器的最大容量
resize使用规则:
- 当n大于当前容器的size时,将size扩大到该值,扩大元素为给出的第二个元素,若未给出默认为0(vector
类的) - 当n小于当前容器的size时,将size缩小到n
reserve使用规则:
- 当n大于当前容器的capacity时,将capacity扩大到该值
- 当n小于当前容器的capacity时,什么也不做.
void test3()
{
vector v(10, 0);
cout << v.size() << endl;//10
cout << v.capacity() << endl;//10
v.reserve(5);
cout << v.size() << endl;//10
cout << v.capacity() << endl;//10
v.reserve(15);
cout << v.size() << endl;//10
cout << v.capacity() << endl;//10
}
void test4()
{
vector v(10, 0);
cout << v.size() << endl;//10
cout << v.capacity() << endl;//10
v.resize(5);
cout << v.size() << endl;//5
cout << v.capacity() << endl;//10
v.resize(15);
cout << v.size() << endl;//15
cout << v.capacity() << endl;//15
}
通过empty判断当前容器是否为空
vector v(10, 0);
cout << v.empty() << endl;//0
begin函数返回的时第一个元素的迭代器,end函数返回的时最后一个元素下一个位置的迭代器
vector v(10, 0);
vector::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;//遍历一遍
rbegin是返回的最后一个元素的迭代器,rend返回的是第一个元素前面的位置的迭代器
vector v(10, 0);
vector::reverse_iterator it = v.rbegin();
while (it != v.rend())
{
cout << *it << " ";
++it;
}
cout << endl;//反向遍历一边
push_back是在容器后面进行尾插,pop_back实在容器后面进行尾删
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
for (auto ch : v)
{
cout << ch << " ";
}
cout << endl;
v.pop_back();
v.pop_back();
v.pop_back();
for (auto ch : v)
{
cout << ch << " ";
}
cout << endl;
通过insert可以在所给的迭代器位置插入一个或多个元素,通过erase可以在所给的迭代器位置删除一个或多个元素 .
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.insert(v.begin(), 0);//在开始位置插入一个0;
v.insert(v.begin(), 2, -1);//在开始位置插入2个-1
v.erase(v.begin());//删除元素第一个位置的元素
v.erase(v.begin(), v.begin() + 2);//删除元素前2个位置的元素
find函数需要给出一段迭代区间,和需要查找的元素,迭代区间是左闭右开的 .
还需要注意其返回值,他在迭代区间内查找出第一个符合的并返回他的迭代器,若未找打则返回迭代区间的最后一个值.
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
vector::iterator pos = find(v.begin(), v.end(),3);
v.insert(pos, 0);
for (auto ch : v)
{
cout << ch << " ";
}
cout << endl;
auto pos1 = find(v.begin(), v.end(), 0);
v.erase(pos1);
for (auto ch : v)
{
cout << ch << " ";
}
cout << endl;
swap函数则是交对象的内容
vectorv1(5, 0);
vectorv2(5, 1);
v1.swap(v2);
vectorv(10, 1);
size_t len = v.size();
for (int i = 0; i < len; i++)
{
cout << v[i] << " ";
}
cout << endl;
vectorv(10, 1);
size_t len = v.size();
for (int i = 0; i < len; i++)
{
cout<
vectorv(10, 1);
for (auto ch : v)
{
cout << ch << " ";
}
cout << endl;
vectorv(10, 1);
vector::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
迭代器的主要主要就是让我们在使用各个容器时不用关心底层的数据结构,而vector的迭代器在底层实际上就是一个指针.迭代器失效指针指向的空间被销毁了,此时指针指向的是一块被销毁的空间,如果在使用就在野指针了.
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
vector::iterator pos = find(v.begin(), v.end(), 3);
v.insert(pos, 30);
//1 2 30 3 4 5
v.erase(pos);
// 1 2 3 4 6
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
vector::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
{
v.erase(it);
}
it++;
}
思维导图: