目录
vector简介:
vector是一个容器,表示大小可以改变的顺序容器。容器中的元素严格连续,是在堆区的一段连续存储空间存储数据的。这段连续的空间是动态开辟的,意味着当容量已满再插入元素时,需要重新动态开辟内存,并将原有数据拷贝到新数组。因为存储数据的空间是连续的,故支持随机访问且比其他的顺序容器访问效率都高(list,deque),vector的尾部插入和删除效率都很高O(1),在其他位置插入或删除效率较低。
构造函数和迭代器
default (1) | explicit vector (const allocator_type& alloc = allocator_type()); |
---|---|
fill (2) | explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); |
range (3) | template <class InputIterator> vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); |
copy (4) | vector (const vector& x); |
(1)默认的无参构造函数(空的vector)
(2)构造一个由n个val组成的数组
(3)用两个迭代器构造(左闭右开构造迭代器之间的元素)
(4)拷贝构造函数(用另一个vector深拷贝)
vector的迭代器是原生指针
正向迭代器
begin:获取第一个数据位置的iterator/const_iterator
end: 获取最后一个数据的下一个位置的iterator/const_iterator反向迭代器(与正向迭代器相反,迭代器的++是往前走)rbegin: 获取最后一个数据位置的reverse_iterator/const_reverse_iteratorrend: 获取第一个数据前一个位置的reverse_iterator/const_reverse_iterator
容量相关函数:
Capacity:(public member function )
size : 获取数据个数capacity : 获取容量大小(在VS下是以1.5倍扩容的,在g++则是2倍)empty : 判断是否为空resize: 改变vector的sizereserve : 改变vector的capacity
增删查改相关函数:
push_back 尾插pop_back 尾删insert 在position之前插入valerase 删除position位置的数据operator[] 像数组一样访问back 返回第一个元素front 返回最后一个元素
非成员函数重载:
swap 交换两个vector的数据(交换底层的指针)
(与string同理,重载std的swap函数,实现时不进行深拷贝,提高效率)
vector的简单实现:
#pragma once
#include<assert.h>
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin() { return _start; }
iterator end() { return _finish; }
const_iterator begin() const{ return _start; }
const_iterator end() const{ return _finish; }
public:
vector()
:_start(nullptr)
,_finish(nullptr)
,_endofstorage(nullptr)
{}
vector(int n, const T& val = T())//参数类型用int,避免与迭代器构造的函数冲突
:_start(nullptr)
, _finish(nullptr)
, _endofstorage(nullptr)
{
resize(n, val);
}
vector(size_t n, const T& val = T())
:_start(nullptr)
, _finish(nullptr)
, _endofstorage(nullptr)
{
resize(n, val);
}
template <class InputIterator>
vector(InputIterator first, InputIterator last)
:_start(nullptr)
, _finish(nullptr)
, _endofstorage(nullptr)
{
while (first != last)
push_back(*first++);
}
void swap(const vector<T>& v)
{
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_endofstorage, v._endofstorage);
}
vector(const vector<T>& v)
:_start(nullptr)
, _finish(nullptr)
, _endofstorage(nullptr)
{
vector<T>tmp(v.begin(), v.end());
swap(tmp);
}
~vector()
{
if (_start)
{
delete[] _start;
_start = _finish = _endofstorage = nullptr;
}
}
size_t size() const { return _finish - _start; }
size_t capacity()const { return _endofstorage - _start; }
bool empty() { return size() == 0; }
void resize(size_t n, const T& val = T())
{
if (n > capacity())
reserve(n);
while (n > size())
*_finish++ = val;
_finish = _start + n;//n < size()
}
void reserve(size_t n)
{
if (n > capacity())
{
size_t sz = size();
T* tmp = new T[n];
if (_start)
{
for (size_t i = 0; i < sz; i++)//逐个数据(赋值)深拷贝
tmp[i] = _start[i];
delete _start;
}
_start = tmp;
_finish = _start + sz;
_endofstorage = _start + n;
}
}
void push_back(const T&val)
{
if (_finish == _endofstorage)
reserve(capacity() == 0 ? 4 : capacity() * 2);
*_finish++ = val;
}
void pop_back()
{
assert(!empty());
--_finish;
}
T& operator[](size_t pos)
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return _start[pos];
}
iterator insert(iterator pos,const T&val)
{
assert(pos >= _start && pos <= _finish);
if (_finish == _endofstorage)
{
size_t n = pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
pos = _start + n;//更新迭代器,避免野指针
}
iterator end = _finish++ ;
while (end != pos)
*end-- = *(end - 1);
*pos = val;
return pos;//返回新插入元素的迭代器,避免迭代器失效
}
iterator erase(iterator pos)
{
assert(pos >= _start && pos < _finish);
iterator end = pos;
while (end != _finish - 1)
*end++ = *(end + 1);
--_finish;
return pos;//返回删除的元素后的一个元素的迭代器,避免迭代器失效
}
void clear() { _finish = _start; }
private:
iterator _start;
iterator _finish;
iterator _endofstorage;
};
简易测试:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
#include"vector.h"
int main()
{
vector<int>v(10, 100);
v.resize(20, 99);
cout << v.size() << endl;
cout << v.capacity() << endl;
for (auto e : v)
cout << e << " ";
cout << endl;
v.insert(v.begin(), 88);
v.insert(v.begin()+6, 88);
v.insert(v.end(), 88);
for (auto e : v)
cout << e << " ";
cout << endl;
return 0;
}
输出: