容器vector是一个可以改变大小的动态数组。
- 序列容器中的元素按严格的线性顺序排序。单个元素通过它们在此序列中的位置进行访问
- 动态数组允许直接访问序列中的任何元素,甚至通过指针算术,并在序列末尾提供相对快速的元素添加/删除。
如何定义和初始化动态数组vector
std::vector<int> nVec;//空数组
std::vector<int> nVec5(5, -1);//5个元素的数组,且初始化值为1
//列表初始化
std::vector<std::string> strVec{ "x", "y", "z" };
如何操作动态数组
- 往数组尾部添加元素: push_back(param);
- 插入元素
std::vector<int>::iterator itr = nVec.begin();
nVec.insert(itr,88);//在itr的位置插入元素88
nVec.insert(itr, 2, 99);//在itr的位置插入两个99
3、删除元素
//查找特定的迭代器
std::vector<int>::iterator iter = std::find(nVec.begin(),nVec.end(),5);
删除特定元素: erase(iter);// iter为迭代器
pop_back()//删除容器尾部数据
删除一段数据
std::vector<int>::iterator firstiter = std::find(nVec.begin(), nVec.end(), 3);
std::vector<int>::iterator lastiter = std::find(nVec.begin(), nVec.end(), 6);
//删除一段数据
nVec.erase(firstiter, lastiter);
//删除所有元素
//nVec.erase(nVec.begin(), nVec.end());
//nVec.clear();//清除所有元素
4、元素的访问
下标访问: nVec[index]
迭代器访问
5、动态数组赋值:
等号赋值;区间拷贝赋值assign;同一个值赋值(六个五)assign(6, 5);
动态数组内存管理
vector
的元数据存储在栈区,而实际的元素数组存储在堆区,并且数组的大小是根据需要动态改变的。在需要更多内存时,vector
会重新分配堆区内存,并将元素从旧内存复制到新内存中。这样可以实现 vector
的动态大小和灵活性。
- 动态调整内存,每一次调整多少,当数组的存储内存不足时候,就会扩张目前的一半内存(可能会和编译器有关,目前用的是vs验证)。
- 内存大小常用的属性函数。
- size;当前存储的数组大小。
- capacity;动态数组目前能在不扩张的情况最多能存的大小。一般capacity大于或者等于size;如果相等时候再增加数据的话,就需要扩展内存,capacity的大小也会随之变化,一般增加当前capacity的一半。
- resize(size_type count): 更改 vector 的大小,使其包含 count 个元素。如果count小于当前的size,则删除掉后面,如果count大于size则后面数据默认0;
- reserve(size_type count): 请求 vector 为至少 count 个元素预留存储空间。
动态数组优缺点
优点:支持随机储存,查询效率高;
缺点:在头部和中间插入删除元素需要移动内存,效率低;
使用场景:适用于元素结构简单,变化小,并且频繁随机访问但不需要对头部和中间元素进行添加删除操作的场景。
例子:
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
std::vector<int> nVec;//空数组
std::vector<int> nVec5(5, -1);//5个元素的数组,且初始化值为1
//列表初始化
std::vector<std::string> strVec{ "x", "y", "z" };
for (int i=3;i<15;i++)
{
nVec.push_back(i);//压入元素到尾端
}
nVec.shrink_to_fit(); //缩小容器大小适应当前
cout << "压入元素的数据:" << endl;
for (int i = 0; i < nVec.size(); i++)
cout << nVec[i] << " ";
cout <<"容器预留大小:"<< nVec.capacity()<<endl;
std::vector<int>::iterator itr = nVec.begin();
nVec.insert(itr,88);//在itr的位置插入元素88
itr = nVec.end();
nVec.insert(itr, 2, 99);//在itr的位置插入两个99
cout << "插入元素的数据:" << endl;
for (int i = 0; i < nVec.size(); i++)
cout << nVec[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
//删除元素
std::vector<int>::iterator iter = std::find(nVec.begin(), nVec.end(), 5);
nVec.erase(iter);// iter为迭代器
std::vector<int>::iterator firstiter = std::find(nVec.begin(), nVec.end(), 3);
std::vector<int>::iterator lastiter = std::find(nVec.begin(), nVec.end(), 6);
//删除一段数据
nVec.erase(firstiter, lastiter);
//删除所有元素
//nVec.erase(nVec.begin(), nVec.end());
//nVec.clear();//清除所有元素
nVec.pop_back();
cout << "删除元素的数据:" << endl;
for (int i = 0; i < nVec.size(); i++)
cout << nVec[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
//赋值操作
std::vector<int> vector;
vector = nVec;
cout << "等号赋值数据:" << endl;
for (int i = 0; i < vector.size(); i++)
cout << vector[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
vector.assign(nVec.begin() + 1, nVec.end() - 1);
cout << "区间拷贝赋值数据:" << endl;
for (int i = 0; i < vector.size(); i++)
cout << vector[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
/*
vector.assign(6, 5);//六个5
cout << "同一个数值赋值数据:" << endl;
for (int i = 0; i < vector.size(); i++)
cout << vector[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
*/
/*
vector.resize(2);
cout << "resize数据:" << endl;
for (int i = 0; i < vector.size(); i++)
cout << vector[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
*/
vector.reserve(20);
cout << "reserve数据:" << endl;
for (int i = 0; i < vector.size(); i++)
cout << vector[i] << " ";
cout << "容器预留大小:" << nVec.capacity() << endl;
getchar();
}