容器中大量應用前面用於構造的construct和用於析構的distroy以及uninitialized_copy()、uninitialized_fill()和uninitialized_fill_n()。這些函數面對的是未初始化的內存,它們將內存的配置和對象的構造分離。在構造對象的時候對其型別採用判斷,然後根據型別調用不同的函數以達到最大化效率。
vector
vector的數據以及操作方式與array非常相似,兩者的唯一差別在於空間的運用的靈活性。array是靜態空間,一旦配置了就不能改變。而vector是動態空間,隨着元素的加入,它的內部機制會自動擴充空間以容納新元素。vector的實現技術,關鍵在於其對大小的控制以及重新配置的數據移動效率。一旦vector的舊有空間滿載,元素的空間會成倍的增長。
1.vector提供的接口
vector提供的接口:包括得到vector的屬性接口、vector的操作接口以及構造函數:
(1)構造函數:vector()、vector(size_type n、const T& value)、vector(size_type n);
(2)屬性函數:begin、end、size、capacity、empty、operator[]、front和back
(3)操作函數:push_back()、pop_back()、erase()、resize()、clear()。
注:vector沒有pop_front和push_front操作。
注:pop_back返回的值爲void類型,不是刪除元素的值。
注:vector(size_type n、const T& value)這種同時初始化n個元素且初始值爲T,只適用於順序容器。
2.vector的數據結構
vector採用的數據結構非常簡單:線性連續空間,它以兩個迭代器start和finish分別指向配置得來的連續空間中目前已被使用的範圍,並以迭代器end_of_storage指向整塊連續空間的尾端。vector採用的空間配置器爲alloc。
- template<class T,class Alloc = alloc>
- class vector{
- public:
- typedef T value_type;
- typedef value_type* pointer;
- typedef value_type* iterator;//迭代器類型就是元素的指針
- typedef value_type& reference;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- ....
- };
注:容量的擴張必須經歷:“重新配置、元素移動、釋放原空間“等過程。
list
相對於vector的連續空間,list就顯得複雜許多,它的好處是每次插入或刪除一個元素,就配置或釋放一個元素。因此對於空間的運用絕對精確,一點也不浪費。而且對於任何位置的元素插入或刪除,list永遠是常數。
1.list提供的接口
list提供的接口:包括得到list的屬性接口、list的操作接口以及構造函數:
(1)構造函數:list()、list(size_type n、const T& value)、list(size_type n)。
(2)屬性函數:begin、end、empty、size、front和back。
(3)操作函數:push_back()、pop_back()、push_front、pop_front、erase()、resize()、clear()、unique、splice、merge、reverse、sort、insert。
- //pop_front和front函數常常連用
- while(!list.empty()){
- process(list.front());
- list.pop_front();
- }
注:push_front、pop_front,只有list和deque纔有此接口
list本身和list的節點是不同的,下面是list節點:
- template<class T>
- struct __list_node{
- typedef void* void_pointer;
- void_pointer prev;
- void_pointer next;
- T data;
- };
- template<class T,class Ref,class Ptr>
- struct __list_iterator{
- typedef __list_iterato<T,T&,T*> iterator;
- typedef __list_iterato<T,Ref,Ptr> self;
- typedef bidirectional_iterator_tag iterator_category;//雙向迭代器
- tyepdef __list_node<T>* link_type;
- link_type node;//包含了一個指向__list_node節點
- .....
- };
- template<class T,class Alloc = alloc>
- class list{
- protected:
- typedef __list_node<T> list_node;
- public:
- typedef list_node* link_type;
- typedef __list_iterator<T,T&,T*> iterator;//包含的迭代器
- protected:
- link_type node;//包含了一個指向__list_node節點
- .....
- };<span style="font-size:18px;">
- </span>
Deque
vector是單向開口的連續線性空間,deque是一種雙向開口的連續線性空間。所謂雙向開口,就是它的頭尾兩端都可以插入元素。deque和vector最大的差異在於deque允許在常數時間內對起頭端進行元素的插入或移除操作,二在於deque沒有所謂容量(capacity)觀念,因爲它是動態地分段連續空間組合而成,隨時可以增加一段新的空間並連接起來。不會像vector那樣”因舊空間不足而重新配置一塊更大的空間,然後複製元素,再釋放舊空間“這樣的事情在deque是不會發生的。雖然deque也提供Random Access iterator,但它的迭代器並不是普通指針。除非特別需要儘可能選擇vector,而不是deque。
1.deque提供的接口
deque提供的接口:包括得到deque的屬性接口、deque的操作接口以及構造函數:
(1)構造函數:deque()、deque(size_type n、const T& value)、deque(size_type n)。
(2)屬性函數:begin、end、size、empty、maxsize()、operator[]、front和back。
(3)操作函數:push_back()、pop_back()、push_front、pop_front、erase()、resize()、clear()、insert。
deque是一個分段連續的空間,維持了整體連續的假象,deque通過一個管控中心,來實現分段連續的結構:
deque中iterator的設計:
- template<class T,class Ref,class Ptr,size_t BufSize>
- struct __deque_iterator{
- typedef __deque_iterator<T,T&,T*,BufSiz> iterator
- typedef __deque_iterator self;
- typdef T** map_pointer;
- T *cur;
- T *firsr;
- T *lase;
- map_pointer node;//指向管控中心
- ...
- }
- template<class T,class Alloc = alloc,size_t BufSize=0>
- class deque{
- public:
- typedef T value_type;
- typedef T* pointer;
- public:
- typedef __deque_iterator<T,T&,T*,BufSiz> iterator;
- protected:
- typedef pointer* map_pointer;
- iterator start;
- iterator finish;
- map_pointer map;
- size_type map_size;
- }
stack
stack是一種先進後出(FILO)的數據結構。它只有一個出口,形式如圖所示。stack允許新增元素、移除元素、取得最頂元素。但除了最頂元素外,沒有其他任何方法可以存取stack的其他元素。換言之,stack不允許有任何遍歷行爲。(stack沒有迭代器)
底層結構通過將deque爲底部結構並封閉器頭端口,便可輕而易舉形成了一個stack。實際上stack可以用list作爲結構,將一端封死就行了。
1.stack提供的接口
stack提供的接口:包括得到stack的屬性接口、stack的操作接口以及構造函數:
(1)構造函數:stack()。
(2)屬性函數:size、empty、top。
(3)操作函數:push、pop。
注:pop返回類型爲void,所以經常以top和pop一起使用。2.stack的數據結構
- template<class T,class sequece=deque<T> >
- class stack{
- protected:
- Sequence c;//所有的接口轉到調用C的接口但是隻操作一端
- }
queue
queue是一種先進後出(FIFO)的數據結構。它有兩個出口,形式如圖所示。stack允許新增元素、從底端移除元素、取得最頂元素。但除了底端可以加入,最頂端可以取出外,沒有其他任何方法可以存取queue的其他元素。換言之,queue不允許有任何遍歷行爲。(queue沒有迭代器)
底層結構通過將deque爲底部結構,改一下接口使其符合”先進先出“的特性。實際上queue可以用list作爲結構,將一端封死就行了。
1.queue提供的接口
stack提供的接口:包括得到stack的屬性接口、stack的操作接口以及構造函數:
(1)構造函數:queue()。
(2)屬性函數:size、empty、front和back。
(3)操作函數:push、pop。
注:pop返回類型爲void,所以經常以front和pop一起使用。2.queue的數據結構
- template<class T,class sequece=deque<T>>
- class queue{
- protected:
- Sequence c;//這個跟上面不同的是兩端不封死
- }
heap和priority_queue
heap以vector爲底層接口,並可通過sift_up和sift_down進行堆調整。heap提供的接口:make_heap、sort_heap、push_heap、pop_heap。下面舉一個例子:
- #include<iostream>
- #include<vector>
- #include<algorithm> //必須包含這個頭文件
- using namespace std;
- int main()
- {
- int a[5]={0,1,2,3,4};
- vector<int> ivec(a,a+5);
- make_heap(ivec.begin(),ivec.end());
- for(int i=0;i<ivec.size();++i)
- cout<<ivec[i]<<" ";
- system("pause");
- return 0;
- }
priority_queue有一個優先級的概念。它是利用一個make_heap完成,而heap又是以vector呈現。priority_queue提供的接口:
構造函數:priority_queue(InputIterator first,InputIterator last,const Compare &x)
priority_queue(InputIterator first,InputIterator last)
其他接口:size、empty、top、push和pop。
- template<class T,class sequece=vector<T>,class Compare = less<typename sequence::value_type> >
- class queue{
- protected:
- Sequence c;
- Compare comp;
- }
下面舉一個例子,注意必須包括queue頭文件。
- #include<iostream>
- #include<vector>
- #include<queue>
- //#include<algorithm>
- using namespace std;
- int main()
- {
- int a[5]={0,1,2,3,4};
- priority_queue<int> ivec(a,a+5);
- while(!ivec.empty()){
- cout<<ivec.top()<<" ";
- ivec.pop();
- }
- system("pause");
- return 0;
- }
slist
slist是一種單鏈表結構,slist和list的差別:list提供的Bidirectional iterator迭代器,而slist提供的是Forward Iterator。slist和list共同具有的特色是他們的插入、移除、結合等操作並不會造成迭代器失效。插入操作會將新元素插入於指定位置之前,而非之後。這樣slist每次插入都要從頭遍歷找到前一個節點。
1.slist提供的接口
slist提供的接口:包括得到slist的屬性接口、slist的操作接口以及構造函數:
(1)構造函數:slist()。
(2)屬性函數:begin、size、empty、front。
(3)操作函數:front、pop_front、push_front。
2.slist的數據結構
- struct __slist_node_base{
- __slist_node_base *next;//可以作爲頭節點
- }
- template<class T>
- struct __slist_node:public __slist_node_base{
- T data;
- }
- struct __slist_iterator_base{
- typedef forward_iterator_tag iterator_category;
- __slist_node_base *node;
- ...
- }
- template<class T,class Ref,class Ptr>
- struct __slist_iterator: public __slist_iterator_base{
- typedef __slist_iterator<T,T&,T*> iterator;
- ...
- }
- template<class T,class Alloc=alloc>
- class slist{
- typedef __slist_node<T> list_node;
- typedef __slist_iterator<T,T&,T*> iterator;
- ...
- }