今天,我們來模擬實現vector。
首先,我們來講一下vector的特性:
1:能夠存放各種類型的動態增容的順序容器
2:支持隨機訪問。
也就是說,他的對象創建之後,當插入一個數據時,可以自己動態的開闢空間,不需要程序員手動的開闢。並且這個數據可以是任意類型的。因爲vector實現了operator[]這個接口,使得他支持隨機訪問。
vector有三個主要的成員變量,分別是:
start:數據起始位置。
finish:所存放的最後一個元素的下一個位置。
endofstarge:所開闢的空間的最後一個位置的下一個位置。
如下圖所示:
紅色部分爲已存儲的空間。最後四格爲開闢好的空間,但是還沒有存儲的數據的空間。
vector的優點與缺點:
優點:
(1)支持隨機訪問,即[]和at()。
(2)節省空間。相比較鏈表而言(鏈表每個節點不僅要存儲內部值的大小還是要存儲指向下個節點和上個節點的指針)
(3)可以像數組一樣的操作。
缺點:
(1)在內部進行增刪效率較低。
(2)只能在vector的最後進行push和pop操作。不能再開頭進行push和pop操作。
(3)當capacity滿時,再插入數據,數據的開闢,拷貝,釋放代價大。
接下來,再說說vector的模擬實現的接口。
(1)push_back
//在這裏,_start,_finish,_endofstarge分別對應着上面所述的start,finish,endofstarge.
void CheckCapacity()//檢查是否需要擴容。
{
size_t Size = _size();//存儲的元素的數量
size_t Capacity = _capacity();//開闢空間的大小
if (_finish == _endofstarge)//該條件成立說明開闢的空間已經被全部存上了數據
{
//Capacity > 0 ? Capacity * 2 : 3;
if (Capacity)
{
Capacity = Capacity * 2;
}
else
{
Capacity = 3;
}
T* _tmp = new T[Capacity];//開闢新的空間
for (size_t i = 0; i < _size(); i++)
{
_tmp[i] = _start[i];//將舊的空間的全部數據拷貝至新的空間
}
delete[] _start;//釋放舊空間
_start = _tmp;
_finish = _tmp + Size;
_endofstarge = _tmp + Capacity;
}
}
void Push_back(const T& x)
{
CheckCapacity();
*_finish = x;//push進新數據。
_finish++;
}
(2)在某一個位置插入一個值
void Insert(Iterator pos, const T& x)
{
CheckCapacity();//檢查是否需要擴容
Iterator it1 = Begin();
if (pos != it1)如果所要找到的位置是否是頭爲兩種考慮方式。
{
while (it1 != End())//輪詢依次找到所要找的位置。
{
if (it1 == pos)
{
break;
}
++it1;
}
}
//這裏插入的方法是找到對應的位置後,將該位置及其以後的元素全部後移一位。
Iterator it2 = End();
while (it2 != it1)
{
--it2;
T a = *it2;
Iterator it = it2;
*(++it) = a;
}
*it2 = x;//插入新元素
++_finish;
}
(3)刪除一個某一個值爲x元素
//當找到這個元素時,需要將這個元素後面的所有元素全部前移一個位置。
//並且刪除的是當前這個數組裏所有出現的這個值。
void Earse(const T& x)
{
Iterator it1 = Begin();
while (it1 != End())
{
if (*it1 == x)
{
Iterator it = it1;
++it;
while (it != End())
{
T a = *it;
*(it - 1) = a;
++it;
}
if(it1 != Begin())
--it1;
_finish--;
}
++it1;
}
}
謝謝大家。