C++容器(順序容器、關聯容器)

轉載:http://hi.baidu.com/36470902/blog/item/50ed5a8b21491f1bc9fc7a3b.html

相關文章:http://wenku.baidu.com/view/98afcf51ad02de80d4d840e3.html

容器主要分爲順序容器和關聯容器。


一,順序容器

vector--連續存儲的元素,單向的
list----由節點組成的不連續存儲的雙向鏈表
deque--連續存儲的元素,雙向的


1,順序容器主要分爲vector, deque, list。
2,容器內的元素類型必須至少滿足2個條件:可複製和可賦值。
3,list容器的迭代器,不支持算術運算,不支持關係運算,也沒有下標操作,只有最簡單的自增 自減 相等 不等 運算。
4,所有的 迭代器範圍都是左閉合區間,  [beg,end)  包括beg,但不包括end
5,順序容器定義的幾種類型:
size_type  容器大小
iterator  迭代器, reverse_iterator 逆序迭代器
const_iterator 只讀迭代器(指向的元素只讀),  const_reverse_iterator
difference_type  迭代器的差值,可爲負值
value_type 元素類型
reference 相當於 value_type&,即指向迭代器對應的元素
const_reference 相當於const value_type &

6,a.begin()  a.end() 對應於 iterator;a.rbegin()   a.rend() 對應於reverse_iterator,
注意,如果a是const的,那麼iterator也必須是const_iterator的

7,添加元素的擦作
a.push_back(t);  在a末尾增加元素t;
a.push_front(t);  在a前端增加元素t,只使用於list和deque
a.insert(p,t);  在迭代器p前面插入元素t,返回新元素的迭代器
a.insert(p,n,t); 在迭代器p前面插入n個元素t,返回void
a.insert(p,b,e);在迭代器p前面插入迭代器b,e標記的範圍內的元素,返回void

8,刪除元素的操作
a.pop_back();刪除a的最後一個元素,返回void,如果a爲空,則函數未定義
a.pop_front();刪除a的第一個元素,返回void;如果a爲空,則函數未定義;只適用於list和deque
a.erase(p);  刪除迭代器p指向的元素,返回下一個元素的迭代器;
a.erase(b,e);刪除迭代器b,e之間的元素,返回下一個元素的迭代器
a.clear();刪除a的所有元素,返回void

9,容器空間大小的操作
a.size() 元素個數  c.max_size() 最大元素個數
a.empty() bool值,指示a是否爲空
c.resize(n,t) 重置c的大小爲n,且 新增加的元素初始化爲t。

10,  a.begin()  a.end()指向iterator
a.front()  a.back() 指向reference
注意,vector<int>::reference  last=a.back(), last1=*--a.end();
,a.back指向最後一個元素,a.end指向最後一個元素的下一位置

11,順序容器的賦值操作
c1=c2;  
c1.swap(c2);  c1 c2 互換
c.assign(b,e);  將迭代器b,e之間的元素複製給c
c.assign(n,t); 將c設置爲n個值爲t的元素

以上操作,都是首先刪除c原來的所有元素後再進行的操作


二,順序容器適配器(adaptor)

stack--後進先出的排列,類似 堆    #include<stack>
queue--先進先出的排列,隊列
priority_queue--優先隊列               #include<queue>

1,適配器的初始化
適配器都是建立在某個順序容器之上的。

stack<int> stk(deg);
其中,deg爲deque<int>;

也就是說,創建適配器時,一般將一個順序容器指定爲其原本。

默認的stack和queue是基於deque實現的。
priority_queue則默認在vector上實現。

但是,實際上
statck可以建立在vector,list,deque任何一種容器之上
queue要求關聯容器提供front操作,所以只有list和deque滿足
priority_queue要求提供隨機訪問功能 ,所有隻有vector和deque滿足

如果適配器不是建在其默認類型上,則必須顯式的指定其關聯類型
stack<int, vector<int> >  stk(ve);
其中ve爲vector<int>類型。

2,棧適配器stack的使用
先進後出
stk.empty()  bool,空爲true
stk.size()    元素個數
stk.pop()  刪除棧頂元素,但是不返回其值
stk.top()  返回棧頂元素,但不刪除其值
stk.push(item);  在棧頂壓入item元素

3,隊列和優先級隊列
先進先出,優先級隊列則按照優先級


三,關聯容器(associative container)

map,multimap 類 --#include<map>
set , multiset 類 -- #include<set>

關聯容器,通過 鍵 存儲和讀取元素。順序容器,通過元素在容器中的位置順序存儲和讀取元素。

關聯容器map的用法:
1,map的定義
map<k,v> m;   k爲鍵類型,v爲值類型
map<k,v> m(m2);
map<k,v> m(b,e); 將迭代器b e 之間的元素複製到m

2,鍵類型必須滿足嚴格弱排序,即 < 一定要定義,且大於 等於時都視爲等於關係
如 p1<p2,表示p1.first()<p2.first() ||  (!(p1.first()<p2.first)&&p1.second()<p2.seconf() )

3,map的類型
map<k,v>::key_type  鍵類型,而且是const的, const k
map<k,v>::mapped_type  值類型,v
map<k,v>::value_type  鍵-值對應的pair類型,pair<k,v>

4,使用下標訪問map對象,可以直接添加新元素
map<string,int> w;   w["ab"]=2;
如果w中不存在ab鍵,則會自動添加一個value_type,設置爲"ab"--2

5,對map迭代器解引用,返回value_type
對map進行下標操作,返回mapped_type

6,map.insert(e);  e爲pair類型,如果其鍵不存在,則新建;如果鍵已經存在,則m不變;
返回值爲pair類型,其中pair.first爲指向此鍵的迭代器, pair.second爲bool,指示是否插入了該元素。
m.insert(beg,end); 插入迭代器範圍,返回void,規則同上
m.insert(iter,e); iter爲迭代器,以iter爲起點搜索,查找是否有e.first對應的鍵元素,如果沒有,則插入e。返回一個迭代器,指向具有e.first鍵的元素

7,刪除map中元素
m.erase(k); 刪除鍵k對應元素,返回刪除個數(map中,只能爲0或者1)
m.erase(p);刪除迭代器p對應元素,返回void
m.erase(b,e);刪除迭代器b e之間元素,返回boid

8,檢查map中鍵是否存在
m.count(k)  返回鍵k在m中出現的次數
m.find(k)  返回鍵k在m中首次出現的迭代器;不存在則返回末端迭代器

9,map中,內存存在方式類型list是不連續的。
所以,map的迭代器只有簡單的自增 自減操作,而且map中沒有push  pop相關操作。
但是,map提供下標操作,只是它的下標操作和順序容器是不一樣的。

關聯容器set:
set與map不同的地方在於:set僅有key_type類型,它的value_type 也就是key_type;而且set不提供下標操作。
set也支持count find 操作,類似map。

關聯容器multimap  multiset:
一個鍵可以對應多個實例
1,insert總會添加一個新元素,不管鍵是否存在
2,erase會刪除擁有該鍵的所有元素
3,在multimap中,擁有相同鍵的元素是相鄰存放的 。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章