常見的資料結構:array陣列,list鍊錶,tree樹,stack棧,queue佇列,hash table雜湊表,set集合,map對映……
根據資料在容器中的排列分為:序列式sequence和關聯式associative。
序列式容器之vector
array是靜態空間,一旦配置則無法改變;
vector是動態空間,隨著元素的加入,內部機制會自動擴充新的空間來容納新的元素。
實現技術:對大小的控制和重新配置時的資料移動效率。
擴充空間:配置新空間、資料移動、釋放舊空間。
在sgi中,#include
在stl標準中只需要#include
template
class
vector
void fill_initialize(size_type n, const t& value)
public:
iterator begin()
iterator end()
//容器使用的長度
size_type size() const
//容器可用的長度
size_type capacity() const
bool empty() const
reference operator(size_type n)
//建構函式
//預設建構函式
vector() : start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const t& value)
vector(int n, const t& value)
vector(long n, const t& value)
//顯示版本的建構函式
explicit
vector(size_type n)
//析構函式
~vector()
//第乙個元素引用
reference front()
//最後乙個元素引用
reference back()
//push_back,呼叫了insert_aux
void push_back(const t& x)
else
//以無備用空間
insert_aux(end(), x);
}//pop_back()
void pop_back()
//erase版本一:接受乙個迭代器
iterator erase(iterator position)
//erase版本二:接受二個迭代器。清除迭代器範圍的元素
iterator erase(iterator first, iterator last)
//resize():為容器重新定義長度。
//若new_size小於size則,丟棄多餘部分
//若new_size大於size則,空出的部分進行t型別的值初始化
void resize(size_type new_size, const t& x)
void resize(size_type new_size)
//clear()清空容器
void clear()
protected:
//配置容器並填滿內容,填n個x
iterator allocate_and_fill(size_type n, const t& x)
__stl_unwind(data_allocator::deallocate(result, n));
}
vector維護的是連續線性空間。支援隨機訪問,迭代器型別為randomaccessiterator。
//表示目前使用的空間頭
iterator start;
//表示目前使用的空間尾
iterator finish;
//表示目前可用的空間尾
iterator end_of_storage;
vector實際配置的大小總是大於等於客戶端需求的大小,以備將來的擴充。
增加新元素時,如果超出當時容量,則容量進行兩倍擴充;若兩倍容量不足時,則擴充足夠大的容量。
容量的擴充需要進行:重新配置、元素移動、釋放舊空間。
vector預設使用alloc作為空間配置器;
uninitialized_fill_n()
根據第乙個引數的型別特性type traits決定演算法使用(__true_type
)fill_n()或是反覆呼叫(__false_type
)construct()來完成。
//push_back,呼叫了insert_aux
void push_back(const t& x)
else
//以無備用空間
insert_aux(end(), x);
}
template
void
vector
::insert_aux(iterator position, const t& x)
else
#ifdef __stl_use_exceptions
//若新空間分配失敗,則釋放所有新分配的空間
catch(...)
#endif /* __stl_use_exceptions */
//釋放舊空間
destroy(begin(), end());
deallocate();
//調整迭代器,指向新空間
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}}
兩個引數版本,釋放區域性區間的清除操作示意圖:
1、若備用空間大於等於新增元素個數
(end_of_storage-finish) >= n
計算插入點之後現有的元素個數
elems_after=finish-position;
情況一:1)、若**插入點之後的現有元素個數**大於**新增元素個數**
elems_after>n
情況二:2)、若**插入點之後的現有元素個數**小於等於**新增元素個數**
elems_after<=n
2、若備用空間小於新增元素個數
(end_of_storage-finish) < n
1)決定新的長度。舊長度的兩倍或舊長度+新增元素個數。
len=old_size+max(old_size,n)
2)配置記憶體空間
iterator new_start =data_allocator::allocate(len);
iterator new_finish = new_start;
情況三:3)資料元素的移動
3、如果分配新空間出現異常,則銷毀新分配的記憶體,丟擲異常
# ifdef __stl_use_exceptions
catch(...)
#endif /* __stl_use_exceptions */
4、清除並釋放舊空間記憶體
destroy(start, finish);
deallocate();
5、調整迭代器,指向新空間
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
n=2; elems_after=2; 備用空間end_of_storage-finish=2;
n=4; elems_after=2; 備用空間end_of_storage-finish=3;
n=3; 備用空間end_of_storage-finish=2;
4 序列式容器
template class vector 成員函式舉例 注意其中的記憶體管理 void vector insert iterator position,size type n,const t x else else ifdef stl use exceptions catch endif stl ...
STL學習2 序列容器
三種 vector,list,queue 基礎 陣列,鍊錶,陣列 支援函式 front,back,push back,pop back 可以動態的改變它的大小,可以彼此賦值,但陣列表示位址常量就沒這功能。vector就像陣列一樣,是連續的。在末尾插入非常高效,中間就不行。要想經常在兩端插入刪除,最好...
STL學習筆記 序列式容器list
由於vector的使用,經常會出現迭代器錯誤,主要是因為vector在每次更改完資料就會重新配置,迭代器就會失效,list的結構和vector的設計差異決定了list在這方面具有優越性,list的insert和splice操作不會造成迭代器失效,並且erase也只會是讓當前元素的迭代器失效。list...