什么是vector
1.vector是表示可变大小的数组的序列容器
2.就像数组一样,vector也采用的连续存储空间来存储元素,也就是意味着剋采用下标对vector的元素进行访问,和数组一样高效。但是不像是数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理
3.本质上来讲,vector使用动态分配数组来存储它的元素,当新元素插入时候,这个数组需要被重新分配大小,为了增加存储空间。其做法是,分配一个新的数组,然后将全部的元素移到这个数组,就是贱而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的额时候,vector并不会每次都重新分配大小
4.vector分配空间策略:vector回分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不用的库采用不用的策略权衡空间的使用和重新分配。但是无论如何,重新分配都因该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的
5.因此,vector占用了更多的存储空间,为了获取管理储存空间的能力,并且以一种有效的方式动态增长
6.与其它动态序列容器相比,vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其他不再末尾的删除和插入,效率更低,比起list和forward_lists统一的迭代器和引用更好
vector的使用
vector的定义
构造函数声明 接口说明
vector() 无参构造
vector(size_type n, const value_type& val = value_type()) 构造并初始化n个val
vector (const vector& x); 拷贝构造
vector (InputIterator first, InputIterator last); 使用迭代器进行初始化构造
迭代器的使用
begin() 获取第一个数据位置的iterator
end() 获取最后一个数据的下一个位置的iterator
rbegin() 获取最后一个数据位置的reverse_iterator
rend() 获取第一个数据前一个位置的reverse_iterator
cbegin() 获取第一个数据位置的const_iterator
cend() 获取最后一个数据的下一个位置的const_iterator
vector空间增长
size() 获取数据个数
capacity() 获取容量大小
empty() 判断是否为空
void resize (size_type n, value_type val = value_type()); 改变vector的size
void reserve (size_type n); 改变vector放入capacity
这里需要注意的是:
capacity的代码在vs下capacity是按1.5倍增长的,gcc是按2倍增长的;
reserve只负责开辟空间,如果确定知道需要多少空间,reserve可以缓解vector增容的代价缺陷问题
resize在开空间的同时还会进行初始化
vector的增删查改
void push_back (const value_type& val); 尾插
void pop_back(); 尾删
InputIterator find (InputIterator first, InputIterator
last, const T& val);
查找。(注意这个是算法模块实现,不是vector的成员接口)
iterator insert (iterator position, const
value_type& val); 在position之前插入val
iterator erase (iterator position); 删除position位置的数据
void swap (vector& x); 交换两个vector的数据空间
reference operator[] (size_type n); 像数组一样访问
vector迭代器失效的问题
// insert导致的迭代器失效
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(int));
// 使用find查找3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
// 删除pos位置的数据,导致pos迭代器失效。
v.erase(pos);
cout << *pos << endl; // 此处会导致非法访问
// 在pos位置插入数据,导致pos迭代器失效。
// insert会导致迭代器失效,是因为insert可
// 能会导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了。
pos = find(v.begin(), v.end(), 3);
v.insert(pos, 30);
cout << *pos << endl; // 此处会导致非法访问
return 0;
}
//erase导致的迭代器失效
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(int));
// 实现删除v中的所有偶数
// 下面的程序会崩溃掉,如果是偶数,erase导致it失效
// 对失效的迭代器进行++it,会导致程序崩溃
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
v.erase(it);
++it;
}
// 以上程序要改成下面这样,erase会返回删除位置的下一个位置
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
it = v.erase(it);
else
++it;
}
return 0;
}
模拟实现
#include <iostream>
#include <string>
#include <assert.h>
#include <algorithm>
using namespace std;
template<class T>
class Vector
{
public:
//Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
void PushBack(const T& val)
{
Insert(end(), val);
}
void PopBack()
{
Erase(end() - 1);
}
void Swap(Vector<T>& v)
{
swap(_start, v._start);
swap(_finish, v._finish);
swap(_endOfStorage, v._endOfStorage);
}
const Vector<T> operator=(Vector<T> v) const
{
Swap(v);
return *this;
}
Vector<T> operator=(Vector<T> v)
{
Swap(v);
return *this;
}
void Insert(iterator pos, const T& val)
{
assert(pos <= _finish && pos >= _start);
size_t len = pos - _start;
if (_finish == _endOfStorage)
{
size_t newC = _start == nullptr ? 1 : 2 * Capacity();
Reserve(newC);
}
pos = _start + len;
iterator end = _finish;
while (end > pos)
{
*end = *(end - 1);
end--;
}
*pos = val;
_finish++;
}
void Reserve(size_t n)
{
//调用自定义类型的运算符重载 ,进行深拷贝
if (n > Capacity())
{
int len = Size();
T* tmp = new T[n];
if (_start)
{
for (int i = 0; i < len; ++i)
{
tmp[i] = _start[i];
}
delete[] _start;
}
_start = tmp;
_finish = _start + len;
_endOfStorage = _start + n;
}
}
void Resize(size_t n, const T& val = T())
{
if (n < Size())
{
_finish = _start + n;
}
else
{
if (n > Capacity())
{
Reserve(n);
}
while (_finish != _start + n)
{
*_finish = val;
++_finish;
}
}
}
iterator Erase(iterator pos)
{
assert(pos < _finish && pos >= _start);
iterator begin = pos + 1;
while (begin < _finish)
{
*(begin - 1) = *begin;
begin++;
}
_finish--;
return pos;
}
~Vector()
{
if (_start)
{
delete[] _start;
_start = _finish = _endOfStorage = nullptr;
}
}
size_t Capacity() const
{
return _endOfStorage - _start;
}
size_t Size() const
{
return _finish - _start;
}
bool Empty()
{
return _start == _finish;
}
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin() const
{
return _start;
}
const_iterator end() const
{
return _finish;
}
const T& operator[](size_t pos) const
{
assert(pos < Size());
return _start[pos];
}
T& operator[](size_t pos)
{
assert(pos < Size());
return _start[pos];
}
Vector()
:_start(nullptr)
,_finish(nullptr)
,_endOfStorage(nullptr)
{}
Vector(const Vector<T>& v)
{
//考虑深拷贝
_start = new T[v.Capacity()];
for (int i = 0; i < v.Size(); ++i)
{
_start[i] = v[i];
}
_finish = _start + v.Size();
_endOfStorage = _start + v.Capacity();
}
private:
iterator _start; //指向数据块的开始
iterator _finish; //指向有效数据的尾
iterator _endOfStorage; //指向存储容量的尾
};
template <class T>
void PrintVector(const Vector<T>& v)
{
for (int i = 0; i < v.Size(); i++)
{
//v.operator[](i);
//v[i] = 10;
cout << v[i] << " ";
}
cout << endl;
}
template <class T>
void PrintVectorIterator(const Vector<T>& v)
{
//Vector<T>::const_iterator--->vit;
auto vit = v.begin();
while (vit != v.end())
{
//*vit = 10;
cout << *vit << " ";
++vit;
}
}
template <class T>
void PrintVectorFor(const Vector<T>& v)
{
for (const auto& e : v)
{
cout << e << " ";
}
cout << endl;
}
void testVector()
{
//Vector<int> v;
//v.PushBack(1);
//v.PushBack(2);
//v.PushBack(3);
//v.PushBack(4);
//v.PushBack(5);
//for (int i = 0; i < v.Size(); i++)
//{
// //v.operator[](i);
// cout << v[i] << " ";
//}
//cout << endl;
Vector<string> v2;
v2.PushBack("123");
v2.PushBack("abc");
v2.PushBack("abc");
v2.PushBack("abc");
v2.PushBack("abc");
v2[2] = "789";
auto vit = v2.begin();
*vit = "ghg";
/*PrintVector(v2);
PrintVectorIterator(v2);*/
PrintVectorFor(v2);
}
void TestVector3()
{
Vector<int> v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);
v.PushBack(4);
auto vit = v.begin();
while (vit != v.end())
{
if (*vit % 2 == 0)
vit = v.Erase(vit);
else
++vit;
}
PrintVectorFor(v);
}
void TestVector5()
{
Vector<int> v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);
v.PushBack(4); // int()
// 为了支持泛型,内置类型也可以使用类似于构造函数的方式创建变量
int b = int(); // b = 0
int c = int(3); // c = 3
v.Resize(7, 10);
PrintVectorFor(v);
}
void TestVector6()
{
Vector<int> v;
v.PushBack(1);
v.PushBack(2);
v.PushBack(3);
v.PushBack(4); // int()
Vector<int> v2(v);
Vector<int> v3, v4, v5, v6;
Vector<int> v7;
v7.PushBack(11);
v7.PushBack(12);
v7.PushBack(13);
v7 = v3 = v4 = v5 = v6 = v2;
cout << "v2:" << endl;
PrintVectorFor(v2);
cout << "v3:" << endl;
PrintVectorFor(v3);
cout << "v7:" << endl;
PrintVectorFor(v7);
}
void TestVector2()
{
Vector<string> v;
v.PushBack("1");
v.PushBack("2");
v.PushBack("3");
v.PushBack("4");
v.Insert(v.begin(), "0"); // 01234
v.Insert(v.end(), "5"); // 012345
v.Insert(v.begin() + 1, "a"); // 0a12345
PrintVectorFor(v);
}
int main()
{
TestVector3();
system("pause");
return 0;
}