最近看了侯捷翻译的STL源码剖析,感觉有些启发。
迭代器:
- Allocator 空间配置器,全域函数 construct(), destroy()
- iterator 是个智能指针,可以从原生指标提取出需要的类别。这样,容器需要实现自己迭代器。
容器
- RB tree的在STL的使用还是很广泛的,不仅是map,set也是用的RB tree
- 根据Vector的特点,迭代器就是使用的原生指针,作为迭代器的指针使用
- List的迭代器不是原生指针,因为++实际上不是地址的++,而是取得next指针。list遍历的代码,注意拼写
list<int>::iterator ite; for(ite = ilist.begin(); ite != ilist.end(); ++ite) cout << *ite << ' '; // 0 1 2 3 4 cout << endl; ite = find(ilist.begin(), ilist.end(), 3);
- deque 則是種雙向開口的連續線性空間。所謂雙向開口,意思是可以在頭尾兩端分別做元素的安插和刪除動作,
加新空間便配置一段定量連續空間,串接在整個 deque 的頭端或尾端。deque 的最大任務,便是在這些分段的定量連續空間上,維護其整體連續的假象,並提供隨機存取的介面。避開了「重新配置、複製、釋放」的輪迴,代價則是複雜的迭代器架構。
- stack以deque为底部結構並封閉其頭端開口。因此, SGI STL 便以 deque 做為預設情況下的stack底部結構,stack 的實作因而非常簡單。
- queue以deque為底部結構並封閉其底端的出口和前端的入口,便輕而易舉形成了一個 queue。因此, SGI STL 便以 deque 做為預設情況下的 queue 底部結構。
- heap
如果使用 list 做為 priority queue 的底層機制,元素安插動作可享常數時間。但是要找到 list ㆗的極值,卻需要對整個 list 進行線性掃描。
以 binary search tree (如 5.1 節的 RB-tree)做為 priority queue 的底層機制。這麼一來元素的安插和極值的取得就有 O(logN) 的表現。但是,小题大做。随机性和实现困难。
binary heap 就是一種 complete binary tree (完全二元樹)
- priority heap
priority_queue 帶有權值觀念,其內的元素並非依照被推入的次序排列,而是自動依照元素的權值排列(通常權值以實值表示)。權值最高者,排在最前面。
預設情況下priority_queue 係利用㆒個 max-heap完成,後者是一個以 vector表現的 complete binary tree - set 是一RB tree为基础的实现的。所以,创建和便利的时候会自动从小到大排序。set的iterator 是const iterator不能用之改变大小。因为,改变值会影响RB tree。
- map 几乎所有的操作都只是转调RB tree的操作而已
- multi-set multi-map 都是以可以键值重复的RB tree
- hash table 二叉树具有logarithmic average time,是因为构造在这个假设上:输入数据具有随机性。hash table也插入,删除,搜寻也具有常数平均时间。是以统计为基础的,不依赖输入输入的随机性。
- 碰撞问题,有许多解决办法:线性探索(liner probing),二次探索(quadraticprobing),开链(separate chain)
- hash set 几乎所有的操作都只是转调hash table的操作而已,没有自动排序功能。
算法:
- 算法的泛型化过程。
- copy的效率问题。
构造一个数学表达式