目录
一、vector基本概念
1.vector数据结构和数组非常相似,也称为单端数组,也就是顺序表。
当然也可以用链表实现
2.vector是动态的模板顺序表,可以动态扩展
3。扩展是开辟新的空间,将原有数据拷贝过来,并释放旧空间
创建准备,定义专有的命名空间
#include<iostream>
using namespace std;
namespace mxyvector
{
template<typename T>
class mvector
{
T*_start;
T*_end;//用指针记录数据元素个数,减去_start即为元素个数
T*_endofstorage;//记录容量
二、构造函数
函数类外书写,每个函数前都要声明模板
template<typename T>
mvector<T>::mvector()//无参构造
{
this->_start = this->_end = this->_endofstorage = NULL;
}
template<typename T>
mvector<T>::mvector(T*begin, T*end)//迭代器传参,T*即为iterator
{
size_t len = end - begin;//拷贝所需的空间长度
this->reserve(len);
for (size_t i = 0; i < len; i++)
{
this->_start[i] = begin[i];
this->_end++;
}
}
template<typename T>
mvector<T>::mvector(size_t n, T elmn)//元素传参构造
{
this->reserve(n);
for (size_t i = 0; i < n; i++)
{
this->_start[i] = elmn;
this->_end++;
}
}
template<typename T>
mvector<T>::mvector(const mvector & mvec)//拷贝构造
{
this->reserve(mvec.capacity());
for (size_t i = 0; i < mvec.size(); i++)
{
this->_start[i] = mvec._start[i];
this->_end++;
}
}
三、assign()赋值函数
template<typename T>
void mvector<T>::assign(T*begin, T* end)
{
this->clear();//先清除原有数据
size_t len = end - begin;
this->reserve(len);//空间开辟
for (size_t i = 0; i < len; i++)
{
this->_start[i] = begin[i];
this->_end++;
}
}
template<typename T>
void mvector<T>::assign(size_t n, T elmn)
{
this->clear();
this->reserve(n);
for (size_t i = 0; i < n; i++)
{
this->_start[i] = elmn;
this->_end++;
}
}
四、empty()函数
template<typename T>
bool mvector<T>::empty()
{
return this->_start == this->_end;//如果头尾指针相同,则未存任何元素,为空
}
五、capacity()函数及size()函数
template<typename T>
size_t mvector<T>::capacity()const
{
return this->_endofstorage - this->_start;//地址相减得长度
}
template<typename T>
size_t mvector<T>::size()const
{
return this->_end - this->_start;
}
六、resize()函数
设定指定大小的空间
template<typename T>
void mvector<T>::resize(size_t num)
{
if (num <= this->size())//指定任意大小空间
{
this->_end = this->_start + num;//重新指定尾指针
this->_endofstorage = this->_start + num;
return;
}
if (num > this->capacity())//扩大开辟空间
this->reserve(num);
}
template<typename T>
void mvector<T>::resize(size_t num, T elmn)//则个加个初始化赋值
{
if (num <= this->size())
{
this->_end = this->_start + num;
this->_endofstorage = this->_start + num;
return;
}
if (num > this->capacity())
{
size_t len = this->size();
this->reserve(num);
for (size_t i = len; i < num; i++)
{
this->_start[i] = elmn;
this->_end++;
}
}
}
七、push_back()尾插函数
template<typename T>
void mvector<T>::push_back(T elmn)
{
this->reserve(this->size()+1);
this->_start[this->size()] = elmn;
this->_end++;
}
八、pop_back()尾删函数
template<typename T>
void mvector<T>::pop_back()
{
this->_end -= 1;//尾指针后退一位就行
}
九、insert()插入函数
插入函数的设计:先开辟对应大小空间,再将pos位置后的数据进行移动,再赋上设定值
template<typename T>
void mvector<T>::insert(const_iterator pos, T elmn)
{
this->reserve(this->size()+ 1);//检查空间是否足够大
T* end = this->_end- 1;//指向最后一个元素
while (end >= pos)
{
*(end + 1) = *end;//移位覆盖
end--;
}
*(end+1) = elmn;//插入元素
this->_end++;
}
template<typename T>
void mvector<T>::insert(iterator pos, size_t count, T elmn)
{
size_t len1 = pos - this->_start, len2 = this->size();
this->reserve(this->size() + count);
pos = this->_start+len1;//pos地址可能会由于扩容改变,需要重新赋值
for(size_t i=0;i<count;i++)
{
for (size_t j = 0; j < len2; j++)
this->_end[i-j] = this->_end[i-j-1];//循环移位
pos[i] = elmn;//给挪出来的空间赋值
}
this->_end += count;
}
十、erase()删除函数
template<typename T>
void mvector<T>::erase(iterator pos)
{
for (iterator i = pos; i < this->_end - 1; i++)//移位覆盖清除
*i = *(i + 1);
this->_end -= 1;
}
template<typename T>
void mvector<T>::erase(iterator begin, iterator end)
{
size_t len = end - begin;
for (iterator i = begin; i < end; i++)
*i = *(i + len);
this->_end -= len;
}
十一、clear()清空函数
template<typename T>
void mvector<T>::clear()
{
this->erase(this->begin(), this->_end);
}
十二、at()元素访问函数
template<typename T>
T&mvector<T>::at(size_t index)
{
return *(this->_start + index);
}
十三、front(),back()获取头尾元素
template<typename T>
T&mvector<T>::front()
{
return *this->_start;
}
template<typename T>
T&mvector<T>::back()
{
return *(this->_end-1);//返回最后一个元素
}
十四、swap()交换函数
template<typename T>
void mvector<T>::swap(mvector & mvec)
{
std::swap(this->_start, mvec._start);//运用库函数交换
std::swap(this->_end, mvec._end);
std::swap(this->_endofstorage, mvec._endofstorage);
}
十五、reserve()预开辟空间函数
template<typename T>
void mvector<T>::reserve(size_t len)
{
if (len >this->capacity())
{
size_t sz = this->size();
T* tmp = new T[len];
if (this->_start)
{
for (size_t i = 0; i < sz; i++)
tmp[i] = this->_start[i];
delete[] _start;
}
this->_start = tmp;
this->_end = tmp + sz;//end指向最后一个元素的下一位
this->_endofstorage = _start + len;
}
}
十六、begin(),end()迭代器
这部分类外写报错,只好写在类中了
iterator&begin()
{
return this->_start;
}
iterator&end()
{
return this->_end;
}
const_iterator&begin()const
{
return this->_start;
}
const_iterator&end()const
{
this->_end;
}
十七、运算符重载
这部分就重载了【】和赋值=,其他的比较函数还有输入输出流函数也可以重载
template<typename T>
mvector<T>&mvector<T>::operator=(const mvector & mvec)
{
this->reserve(mvec.capacity());
for (size_t i = 0; i < mvec.size(); i++)
{
this->_start[i] = mvec._start[i];
this->_end++;
}
return *this;
}
template<typename T>
T&mvector<T>::operator[](size_t index)
{
return *(this->_start + index);
}
十八、析构函数
释放_start指向的空间内存
template<typename T>
mvector<T>::~mvector()
{
if(this->_start)
delete[]this->_start;
this->_start = this->_end = this->_endofstorage = NULL;
}
十九、vector全部模拟实现源码
#include<iostream>
using namespace std;
namespace mxyvector
{
template<typename T>
class mvector
{
T*_start;
T*_end;//用指针记录数据元素个数,减去_start即为元素个数
T*_endofstorage;//记录容量
public:
typedef T* iterator;//因使用模板,必须定义在类中
typedef const T* const_iterator;
mvector(); //采用模板实现类实现,默认构造函数
mvector(T*begin, T*end); //将v[begin(),ens()]区间的元素拷贝给本身
mvector(size_t n, T elmn); //构造函数将n个elem拷贝给本身
mvector(const mvector&mvec); //拷贝构造函数
mvector&operator=(const mvector&mvec); //重载=号
void assign(T* begin, T* end); //将[begin,end]区间中的数据拷贝复制给本身
void assign(size_t n, T elmn); //将n个elem拷贝给本身
bool empty(); //判断容器是否为空
size_t capacity()const; //容器容量
size_t size()const; //容器中元素的个数
void resize(size_t num); //重新指定容器的长度为num,变长用默认值填充新位置,变短删除超出元素
void resize(size_t num, T elmn); //重新指定容器的长度为num,变长用elmn填充新位置,变短删除超出元素
void push_back(T elmn); //尾插一个元素
void pop_back(); //尾删一个元素
void insert(const_iterator pos, T elmn); //迭代器指向位置pos插入元素elmn
void insert(iterator pos, size_t count, T elmn); //迭代器指向位置pos插入count个元素elmn
void erase(iterator pos); //删除迭代器指向的元素
void erase(iterator begin, iterator end); //删除迭代器葱begin到end之间的元素
void clear(); //删除容器中所有元素
T&at(size_t index); //返回索引index所指的数据
T&operator[](size_t index); //返回索引index所指的数据
T&front(); //返回容器中的第一个元素
T&back(); //返回容器中的最后一个数据元素
void swap(mvector&mvec); //将mvec与本身的元素互换
void reserve(size_t len); //容器预留len个元素长度,预留位置不初始化,元素不可访问
iterator&begin()
{
return this->_start;
}
iterator&end()
{
return this->_end;
}
const_iterator&begin()const
{
return this->_start;
}
const_iterator&end()const
{
this->_end;
}
~mvector(); //析构函数
};
template<typename T>
mvector<T>::mvector()
{
this->_start = this->_end = this->_endofstorage = NULL;
}
template<typename T>
mvector<T>::mvector(T*begin, T*end)
{
size_t len = end - begin;//拷贝所需的空间长度
this->reserve(len);
for (size_t i = 0; i < len; i++)
{
this->_start[i] = begin[i];
this->_end++;
}
}
template<typename T>
mvector<T>::mvector(size_t n, T elmn)
{
this->reserve(n);
for (size_t i = 0; i < n; i++)
{
this->_start[i] = elmn;
this->_end++;
}
}
template<typename T>
mvector<T>::mvector(const mvector & mvec)
{
this->reserve(mvec.capacity());
for (size_t i = 0; i < mvec.size(); i++)
{
this->_start[i] = mvec._start[i];
this->_end++;
}
}
template<typename T>
mvector<T>&mvector<T>::operator=(const mvector & mvec)
{
this->reserve(mvec.capacity());
for (size_t i = 0; i < mvec.size(); i++)
{
this->_start[i] = mvec._start[i];
this->_end++;
}
return *this;
}
template<typename T>
void mvector<T>::assign(T*begin, T* end)
{
this->clear();//先清除原有数据
size_t len = end - begin;
this->reserve(len);
for (size_t i = 0; i < len; i++)
{
this->_start[i] = begin[i];
this->_end++;
}
}
template<typename T>
void mvector<T>::assign(size_t n, T elmn)
{
this->clear();
this->reserve(n);
for (size_t i = 0; i < n; i++)
{
this->_start[i] = elmn;
this->_end++;
}
}
template<typename T>
bool mvector<T>::empty()
{
return this->_start == this->_end;//如果头尾指针相同,则未存任何元素,为空
}
template<typename T>
size_t mvector<T>::capacity()const
{
return this->_endofstorage - this->_start;//地址相减
}
template<typename T>
size_t mvector<T>::size()const
{
return this->_end - this->_start;
}
template<typename T>
void mvector<T>::resize(size_t num)
{
if (num <= this->size())//指定任意大小空间
{
this->_end = this->_start + num;//重新指定尾指针
this->_endofstorage = this->_start + num;
return;
}
if (num > this->capacity())//扩大开辟空间
this->reserve(num);
}
template<typename T>
void mvector<T>::resize(size_t num, T elmn)//则个加个初始化赋值
{
if (num <= this->size())
{
this->_end = this->_start + num;
this->_endofstorage = this->_start + num;
return;
}
if (num > this->capacity())
{
size_t len = this->size();
this->reserve(num);
for (size_t i = len; i < num; i++)
{
this->_start[i] = elmn;
this->_end++;
}
}
}
template<typename T>
void mvector<T>::push_back(T elmn)
{
this->reserve(this->size()+1);
this->_start[this->size()] = elmn;
this->_end++;
}
template<typename T>
void mvector<T>::pop_back()
{
this->_end -= 1;//尾指针后退一位就行
}
template<typename T>
void mvector<T>::insert(const_iterator pos, T elmn)
{
this->reserve(this->size()+ 1);//检查空间是否足够大
T* end = this->_end- 1;//指向最后一个元素
while (end >= pos)
{
*(end + 1) = *end;//移位覆盖
end--;
}
*(end+1) = elmn;//插入元素
this->_end++;
}
template<typename T>
void mvector<T>::insert(iterator pos, size_t count, T elmn)
{
size_t len1 = pos - this->_start, len2 = this->size();
this->reserve(this->size() + count);
pos = this->_start+len1;//pos地址可能会由于扩容改变,需要重新赋值
for(size_t i=0;i<count;i++)
{
for (size_t j = 0; j < len2; j++)
this->_end[i-j] = this->_end[i-j-1];//循环移位
pos[i] = elmn;//给挪出来的空间赋值
}
this->_end += count;
}
template<typename T>
void mvector<T>::erase(iterator pos)
{
for (iterator i = pos; i < this->_end - 1; i++)//移位覆盖清除
*i = *(i + 1);
this->_end -= 1;
}
template<typename T>
void mvector<T>::erase(iterator begin, iterator end)
{
size_t len = end - begin;
for (iterator i = begin; i < end; i++)
*i = *(i + len);
this->_end -= len;
}
template<typename T>
void mvector<T>::clear()
{
this->erase(this->begin(), this->_end);
}
template<typename T>
T&mvector<T>::at(size_t index)
{
return *(this->_start + index);
}
template<typename T>
T&mvector<T>::operator[](size_t index)
{
return *(this->_start + index);
}
template<typename T>
T&mvector<T>::front()
{
return *this->_start;
}
template<typename T>
T&mvector<T>::back()
{
return *(this->_end-1);//返回最后一个元素
}
template<typename T>
void mvector<T>::swap(mvector & mvec)
{
std::swap(this->_start, mvec._start);//运用库函数交换
std::swap(this->_end, mvec._end);
std::swap(this->_endofstorage, mvec._endofstorage);
}
template<typename T>
void mvector<T>::reserve(size_t len)
{
if (len >this->capacity())
{
size_t sz = this->size();
T* tmp = new T[len];
if (this->_start)
{
for (size_t i = 0; i < sz; i++)
tmp[i] = this->_start[i];
delete[] _start;
}
this->_start = tmp;
this->_end = tmp + sz;
this->_endofstorage = _start + len;
}
}
template<typename T>
mvector<T>::~mvector()
{
if(this->_start)
delete[]this->_start;
this->_start = this->_end = this->_endofstorage = NULL;
}
}
二十、main函数测试用例
#include"mvector.hpp"
using namespace mxyvector;
void printMvector(mvector<int>&v)
{
for (auto i : v)//auto自动判断类型,表示从v中逐一读取
cout << i << " ";
cout << endl;
}
void test01()
{
mvector<int>v1;//默认无参构造
for (int i = 0; i < 10; i++)
v1.push_back(i);
printMvector(v1);
//通过区间构造
mvector<int>v2(v1.begin(), v1.end());
printMvector(v2);
//n个elmn构造
mvector<int>v3(7, 3);
printMvector(v3);
//拷贝构造
mvector<int>v4(v3);
printMvector(v4);
}
void test02()
{
mvector<int>v1;
for (int i = 0; i < 10; i++)
v1.push_back(i);
printMvector(v1);
mvector<int>v2;
v2 = v1;
printMvector(v2);
mvector<int>v3;
v3.assign(v1.begin(), v1.end());
printMvector(v3);
mvector<int>v4;
v4.assign(7, 3);
printMvector(v4);
}
void test03()
{
mvector<int>v1;
for (int i = 0; i < 10; i++)
v1.push_back(i);
printMvector(v1);
if (v1.empty())
cout << "v1为空" << endl;
else
{
cout << "v1不为空" << endl;
cout << "v1的容量为:" << v1.capacity() << endl;
cout << "v1的大小为:" << v1.size() << endl;
}
v1.resize(15,3);//指定空间大小
printMvector(v1);
v1.resize(5);
printMvector(v1);
}
void test04()
{
mvector<int>v1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
printMvector(v1);
v1.pop_back();
printMvector(v1);
v1.insert(v1.begin(), 100);
printMvector(v1);
v1.insert(v1.begin(), 3, 373);
printMvector(v1);
v1.erase(v1.begin());
printMvector(v1);
v1.erase(v1.begin() + 1, v1.end());
printMvector(v1);
v1.clear();
printMvector(v1);
}
void test05()
{
mvector<int>v1;
for (int i = 0; i < 10; i++)
v1.push_back(i);
for (int i = 0; i < v1.size(); i++)
cout << v1[i] << " ";
cout << endl;
for (int i = 0; i < v1.size(); i++)
cout << v1.at(i) << " ";
cout << endl;
cout << "第一个元素为:" << v1.front() << endl;
cout << "最后一个元素为:" << v1.back() << endl;
}
void test06()
{
mvector<int>v1;
for (int i = 0; i < 10; i++)
v1.push_back(i);
printMvector(v1);
mvector<int>v2;
for (int i = 9; i >=0; i--)
v2.push_back(i);
printMvector(v2);
v1.swap(v2);
printMvector(v1);
printMvector(v2);
}
void test07()
{
mvector<int>v;
v.reserve(100000);//由实现代码知此时_start仍为空指针
int num = 0;
int*p = NULL;
for (int i = 0; i < 100000; i++)
{
v.push_back(i);
if (p != &v[0])
{
p = &v[0];
num++;
}
}
cout << "num=" << num << endl;
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
test07();
}