目錄
一、vector的數據結構
二、vector的構造
三、vector的增刪查改及空間管理
四、全部代碼
一、vector的數據結構
vector以線性連續空間為基礎來定義數據結構以及擴展功能。vector的兩個迭代器,分別是start和finish,分別指向配置得來的已被使用的空間。還有一個迭代器,end_of_storage指向整塊連續空間的尾端。?
iterator _start = nullptr;
iterator _finish = nullptr;
iterator _endofstorage = nullptr;
(此處迭代器變量名前加‘_'表示我們不是真正的vector而是模擬出來的)?
這些迭代器應該被private所修飾,那么,可以設計如下構造函數來提取vector的首尾,這樣既保護了迭代器,又便于提取首位:
iterator begin()
{return _start;
}iterator end()
{return _finish;
}const_iterator begin() const
{return _start;
}const_iterator end() const
{return _finish;
}
vector的實際配置大小要比需求量大一些,以便將來可以擴充。也就是說,vector的容量大小永遠大于或者等于其大小。一旦其容量等于其大小,即是滿載,當有新的元素加入時,vector就要進行擴容。
示意圖如下:?
二、vector的構造
vector的構造如下:
(constructor)構造函數聲明 | 接口說明 |
vector(); | 無參構造 |
vector(size_type n, const value_type& val = value_type()); | 構造并初始化n個val |
vector (const vector& x); | 拷貝構造 |
vector (InputIterator first, InputIterator last); | 使用迭代器進行初始化構造 |
我們來一一實現。
無參構造:
vector()
{}
初始化n個構造:
vector(size_t n, const T& val = T())
{resize(n, val);
}vector(int n, const T& val = T())
{resize(n, val);
}
拷貝構造:
vector(const vector<T>& v)
{_start = new T[v.capacity()];//memcpy(_start, v._start, sizeof(T)*v.size());for (size_t i = 0; i < v.size(); i++){_start[i] = v._start[i];}_finish = _start + v.size();_endofstorage = _start + v.capacity();
}
使用迭代器初始化構造:
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);++first;}
}
除此之外,也可以重載=來實現構造,原理同拷貝構造:
vector<T>& operator=(vector<T> v)
{swap(v);return *this;
}
最后,既然有構造函數,那必然有析構函數呀:
~vector()
{if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}
}
三、vector的增刪查改及空間管理
vector的增刪查改功能函數如下:
vector增刪查改 | 接口說明 |
push_back | 尾插 |
pop_back | 尾刪 |
find | 查找。(注意這個是算法模塊實現,不是vector的成員接口) |
insert | 在position之前插入val |
erase | 刪除position位置的數據 |
swap | 交換兩個vector的數據空間 |
operator[] | 像數組一樣訪問 |
要實現push_back,我們先實現insert:
iterator insert(iterator pos, const T& x)
{assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);pos = _start + len;}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;
}
這樣,在設計push_back時,直接調用insert函數就好:
void push_back(const T& x)
{insert(end(), x);
}
要實現pop_back,不妨參考push_back的實現過程,先實現erase:
iterator erase(iterator pos)
{assert(pos >= _start && pos < _finish);iterator it = pos + 1;while (it != _finish){*(it - 1) = *it;++it;}--_finish;return pos;
}
再直接調用erase即可實現pop_back:
void pop_back()
{erase(--end());
}
要交換兩個vector的數據空間的話,把關鍵迭代器交換即可:
void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);
}
operator[]的實現如下:
T& operator[](size_t pos)
{assert(pos < size());return _start[pos];
}const T& operator[](size_t pos) const
{assert(pos < size());return _start[pos];
}
vector的空間管理功能如下:
容量空間 | 接口說明 |
size | 獲取數據個數 |
capacity | 獲取容量大小 |
empty | 判斷是否為空 |
resize | 改變vector的size |
reserve | 改變vector的capacity |
前三個都很簡單,返回相應的值即可:
size_t size() const
{return _finish - _start;
}size_t capacity() const
{return _endofstorage - _start;
}bool empyt() const
{return ((_endofstorage - _start) == 0 ? true : false);
}
重點實現的是resize和reserve:
resize如下:
void resize(size_t n, const T& val = T())
{if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*_finish = val;++_finish;}}
}
reserve如下:
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;}
}
四、全部代碼
全部代碼如下:
#include<assert.h>namespace bit
{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;}vector(size_t n, const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(){}vector(const vector<T>& v){_start = new T[v.capacity()];for (size_t i = 0; i < v.size(); i++){_start[i] = v._start[i];}_finish = _start + v.size();_endofstorage = _start + v.capacity();}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}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 resize(size_t n, const T& val = T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*_finish = val;++_finish;}}}void push_back(const T& x){insert(end(), x);}void pop_back(){erase(--end());}size_t capacity() const{return _endofstorage - _start;}size_t size() const{return _finish - _start;}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& x){assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);// 解決pos迭代器失效問題pos = _start + len;}iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator it = pos + 1;while (it != _finish){*(it - 1) = *it;++it;}--_finish;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;};
}