vector是定义于命名空间namespace std内的模板,头文件为#include< vector >
vector介绍
vector表示可变大小的序列器vector采用连续的空间来存储数据,所以可以用下标来访问,其空间大小可以动态变化,所以类似于动态数组,因为支持随机访问,所以导致其效率低。vector使用动态分配数组来存储元素,每当容器满了,再插入需要进行扩容时,其会分配一个新数组,将全部元素转移过去,再进行插入操作。vector接口整理
构造函数
函数声明接口说明vector()无参构造函数vector(size_type n,const T& val = T()构造并初始化n个valvector(Inputlterator first,Inputlterator last)用迭代器进行构造vector(const vector& v)拷贝构造函数 vector<int> first(4, 10); //构造4个10 vector<int> second(first); //拷贝构造函数 int m[] = { 1,2,3,4,5 }; vector<int> third(m, m + sizeof(m) / sizeof(m[0]));//使用迭代器初始化 for (auto it : first) { cout << it<<" "; } for (auto it : second) { cout << it << " "; } for (auto it : third) { cout << it << " "; }vector迭代器 [begin,end)
iterator接口说明begin()获取数据的第一个位置end()获取数据最后一个元素的下一个位置rbegin()/rend()反向遍历增删改查
增删改查接口说明push_back()尾插pop_back()尾删_Pop_back_n(size_t n)尾删n个元素find查找insert()在pos位置前面插入erase()删除pos位置上的元素clear()清空容器swap()交换数据空间operator[ ]下标访问push_back()与insert()的区别
push_back()将元素插到vector对象的末尾,insert()将元素插到vector对象的任意位置。 pop_back()尾删操作、erase()可以删除迭代器指定的元素,也可以删除一段区间、clear()删除vector对象的所有元素,类似于erase(begin(),end())
capacity操作
size()返回有效元素个数capacity()返回容器所能容纳的元素数reserve()预设容器容量resize()修改容器大小empty()判空,if==nullptr 返回真 int a[] = { 1,2,3,4,5,6,7,8,9 }; vector<int> v(a, a + sizeof(a) / sizeof(a[0])); //find auto pos = find(v.begin(), v.end(), 3); //insert v.insert(pos, 10); auto it = v.begin(); while (it != v.end()) { cout << *it << " "; it++; } //operator[] 范围for int a[] = { 1,2,3,4,5,6,7,8,9 }; vector<int> v(a, a + sizeof(a) / sizeof(a[0])); v[0] = 10; for (auto e : v) { cout << e <<" "; }迭代器失效
//场景1 ---------因位置删除 int a[] = { 1,2,3,4 }; vector<int> v(a, a + sizeof(a) / sizeof(a[0])); auto pos = find(v.begin(),v.end(),3); //因为erase将pos位置的值删除 v.erase(pos); //导致迭代器失效 cout << *pos << endl; //场景2 ---------因底层扩容 int a[] = { 1,2,3,4 }; vector<int> v(a, a + sizeof(a) / sizeof(a[0])); auto pos = find(v.begin(),v.end(),3); cout << v.capacity() << endl; //insert插入操作,导致底层扩容,但是pos依然指向扩容之前的位置, //但是已经被释放了,导致访问出错 v.insert(pos, 5); v.insert(pos, 6); v.insert(pos, 7);失效场景
所有可能导致底层空间改变的操作 push_back, resize, reaserveerase(it) 删除某个位置解决办法: 重新给迭代器赋值
vector底层模拟实现
namespace bai { template<class T> class vector { public: typedef T* iterator; typedef const T* const_iterator; iterator begin() return _first; iterator end() return _end; const_iterator cbegin() return _first; const_iterator cend() return _end; vector() :_first(nullptr) , _end(nullptr) , _endOfcapacity(nullptr) {} vector(int n, const T& val = T()) :_first(nullptr) ,_end(nullptr) ,_endOfcapacity(nullptr) { reserve(n); while (n--) { push_back(val); } } template<class T> vector(InputIterator start, InputIterator finish) { reverse(finish - start); while (start != finish) { push_back(*start); ++start; } } vector(const vector<T>& v) :_first(nullptr) ,_end(nullptr) ,_endOfcapacity(nullptr) { reverse(v.capacity()); iterator it = begin(); const_iterator vit = cbegin(); while (vit != cend()) { *it++ = *vit++; } _end = _first + v.size(); _endOfcapacity = _first + v.capacity(); } vector& operator(const vector& v) { Swap(v); return *this; } ~vector() { delete[] _first; _first = _end = _endOfcapacity = nullptr; } void Swap(vector<T>& v) { swap(_first, v._first); swap(_end, v, _end); swap(_endOfcapacity, v._endOfcapacity); } private: iterator _first; //指向数据块开头 iterator _end; //指向数据块结尾 iterator _endOfcapacity; //指向容量的尾部 }; }vector:如何创建一个二维数组:
vector<vector<int>> res; res.resize(3); //创建3行 for (auto& e : res) //注意 e.resize(4, 1);//给每行申请4个空间,默认初始化值为1注意:当用vector创建二维数组时,给行申请空间时,最好写成引用,如果不写成引用,导致给行申请空间失败。
