第三講
十八&十九、deque&queue和stack深度探索
1.容器deque
??? 分段連續
vector里面的指針指向buffer
vector怎么雙向增長呢?
所有的容器都維護了兩個迭代器:start和finish。
一個deque的大小是40,start(16)+finish(16)+map(4)+map_size(4)=40
?
?
insert()可以往前或往后推,判斷離頭端近還是尾端近,選擇近的往那一端推。
deque如何模擬連續空間:iterator操作符重載,提供[]操作符。
?
2.容器queue和stack
deque雙向進出
stack先進后出
queue先進先出
queue和stack的底層容器是deque
stack和queue都不允許遍歷,也不提供iterator。
stack和queue都可選擇list或deque作為底層結構。
queue不可選擇vector作為底層結構。stack可選擇vector作為底層結構。
stack和queue都不可選擇set或map作為底層結構。
二十、RB-tree深度探索
關聯式容器底層用紅黑樹和哈希表作支持。
1.容器rb_tree
紅黑樹是平衡二元搜尋樹。排列規則有利search和insert,并保持適度平衡,無任何解答過深。
rb_tree提供遍歷操作及iterators。按正常規則(++ite)遍歷,便能獲得排序狀態。
不應使用rb_tree的iterators改變元素值(因為元素有其嚴謹排列規則)。編程層面并未阻止此事。如此設計是正確的,因為rb_tree即將為set和map服務(作為其底部支持),而map允許元素的data被改變,只有元素的key才是不可改變的。
rb_tree提供兩種insertion操作:insert_unique()和insert_equal()。前者表示節點key在整個tree中獨一無二,否則安插失??;后者表示節點key可重復。
key+data=value
rb_tree大小:12(G2.9),24(G4.9)
2.容器_Rb_tree(G4.9)
使用handle-body。
二十一、set/multiset深度探索
關聯式容器底層用紅黑樹和哈希表作支持。
1.容器set
set/multiset以rb_tree為底層結構,因此有元素自動排序特性。排序的依據是key,而set/multiset元素的value和key合一:value就是key。
set/multiset提供遍歷操作及iterators。按正常規則(++ite)遍歷,便能獲得排序狀態。
無法使用set/multiset的iterators改變元素值(因為元素有其嚴謹排列規則)。set/multiset的iterator是其底部的RB tree的const-iterator,就是為了禁止user對元素賦值。
set元素的key必須獨一無二,因此其insert()用的rb_tree的insert_unique()。
multiset元素的key可以重復,因此其insert()用的rb_tree的insert_equal()。
set的所有操作,都呼叫底層t(紅黑樹)的操作。從這層意義看,set是個container adapter。
2.容器set,in VC6
VC6不提供identity(),_Kfn(內部class)相當于G2.9的identity()。
二十二、map/multimap深度探索
1.容器map
map/multimap以rb_tree為底層結構,因此有元素自動排序特性。排序的依據是key。和set的不同:key和data合成value。
map/multimap提供遍歷操作及iterators。按正常規則(++ite)遍歷,便能獲得排序狀態。
無法使用map/multimap的iterators改變元素的key(因為key有其嚴謹排列規則),但可以用它改變元素的data。因此map/multimap內部自動將user指定的key tyep設為const,禁止user對元素的key賦值。
map元素的key必須獨一無二,因此其insert()用的rb_tree的insert_unique()。
multimap元素的key可以重復,因此其insert()用的rb_tree的insert_equal()。
容器map有四個模板參數,前兩個Key和T(即data)沒有默認值。map把Key和T包成pair<const Key,T>。
2.容器map,in VC6
VC6不提供select1st(),_Kfn(內部class)相當于G2.9的select1st()。
3.容器map,獨特的operator[]
??? 傳回和key相關的data。如果key不存在,會用key創建一個pair,使用默認的data值。
二十三&二十四、hashtable深度探索
1.容器hashtable
如果發生碰撞,把它們放在一個鏈表串起來。Sepatate Chaining。
hashtable一開始有一定量的buckets(vector)。如果元素的個數比buckets個數多,就要rehashing。因為鏈表過長,搜尋速度慢。GUN C中一開始buckets的個數是53,擴展時*2然后找附近的質數即97。數字不是運行時才計算的,而是一開始就編好的。
可以用hashtable iterators改變元素的data,但不能改變元素的key。因為hashtable根據key實現嚴謹的元素排列。
sizeof(hashtable)? = 1 + 1 +1 + sizeof(buckets)(12) + 4 = 19 ->20
GUN C用的單向鏈表,VC用的雙向鏈表。
Hashtable需要指定6個模板參數。
2.hash-function,hash-code
hash function的目的,就是希望根據元素值算出一個hash code(一個可進行modulus運算的值),使得元素經hash code映射之后能夠雜夠亂夠隨機地被置于hashtable內。愈是雜亂,愈不容易發生碰撞。
3.modulus運算
二十五、hash_set/hash_multiset,hash_map/hash_multimap概念
?
二十六、unordered容器概念
??? 只是換了名字,和hash一樣。