STL六大组件的交互关系
container通过allocator取得数据存储空间,algorithm通过iterator存取container中的内容,functor协助algorithm完成不同的策略变化,adapter修饰functor.
STL 的核心思想
把数据容器与算法分开,彼此独立设计。
1.vector
动态增长机制:GCC以2的指数速度增长,vs以1.5倍的速度增长。
而在不断pop的过程中,无论原先分配的空间有多大,都不会动态减少。
迭代器特性:可以以普通指针做迭代器。一旦引起空间重新配置,指向vector的所有迭代器就都失效了。
2.List
List基于双向链表实现
List的插入、删除或者拼合操作不会造成原有迭代器的失效。
List不能用STL 中的sort函数进行排序,而是要用自身的sort函数。List仅支持随机访问迭代器,而List是双向迭代器。
3.deque
是一个双向队列
将数据分为多个存储区域,存储区域的指针存储在map存储区中,当map区域不够大时可以动态增长。所以deque可以在常数时间在首尾进行存取操作,也支持随机访问。
但是代价就是复杂的迭代器,从而导致在许多方面表现的都比vector差。
4.statck
statck可以基于多种容器实现,默认是基于deque
statck只能在尾部对元素进行存取,不允许遍历行为,不提供迭代器。
5.queue
可以基于多种容器实现,默认是deque
值允许在尾部添加元素,在首部删除元素,不允许遍历行为,不提供迭代器。
6.heap
如果用vector来存储二叉树。如果v[1]是根节点,则v[i]的父节点为v[i/2],v[i]的子节点为v[2*i]和v[2*i+1]。真是巧了
插入:先插入,递归地跟父节点相比,直到不需要交换为止。
删除:先将根节点取出,然后将其优先级设置为最低,依次与子节点进行交换,只到达到底层。
STL提供的接口
int myints[] = { 1,3,5,2,4,6 };
vector<int> v(myints, myints + 5);
make_heap(v.begin(), v.end());//默认大顶堆
v.push_back(0);
push_heap(v.begin(), v.end());//先插入数据再调用函数
pop_heap(v.begin(), v.end());//把位于堆顶的元素移至vector的末尾
v.pop_back();//要先pop_heap
sort_heap(v.begin(),v.end());//默认从小到大排序
7.priority_queue
默认是基于vector的大顶堆,没有迭代器,不允许遍历。
8.RB-tree
红黑树可以不平衡,平衡性比val-tree差,但是通常能够达到很好的平衡状态,平均搜索效率和avl-tree几乎相等。
迭代器:是双层迭代器,第一层提供increment()和decrement()操作。第二层基于第一层完成常规的迭代器操作。
红黑树的定义:【1】节点非红即黑【2】红节点的子节点必须为黑节点【3】根节点为黑【4】任何一节点到null的任何路径,所含黑节点数必须相同。
9.set
基于红黑树实现。
不能通过迭代器改变元素值。(如果改变的话会破坏红黑树的结构)。
插入和删除操作都会导致之前的迭代器失效。
对于关联容器,使用自身的find()函数会比使用STL的find()更加有效。
10.map
不能通过迭代器改变key值,但是可以改变value值,删除和插入操作不会使之前的迭代器失效。
Insert操作返回的是pair,first是被插入元素的迭代器,second是bool,表示是否插入成功
Mulimap、mulitset与普通的map和set差不多,只不过是允许有重复值。
11.hash_table
线性探测:f(value)=value%length+i;
二次探测:f(value)=value%length+i^2
开链:相同key值的value以链表的方式保存在同一个桶中。当元素个数大于桶的个数时就重建,然后再插入重建后的相应位置。
hash_map和hash_set都是基于hash_table.
vs说hash_map和hash_set都过时了,要用unordered_map,unorder_set,性能最佳。
12.仿函数
仿函数是行为类型函数的对象,通过继承基本的仿函数类然后实现operator()来实现。仿函数的主要作用是配合STL的算法。
13.sort
Sort() 当数据量大时采用快速排序,一旦分段后的数据量小于某个门槛,为避免快速排序的递归调用带来过大的额外负荷,就改用插入排序,如果递归层次过深(或者一旦发现会有O(N^2)的危险),还会改用堆排序。
14.迭代器总结
拥有迭代器的:vector list deque map set RB-tree
没有迭代器的:stack queue priority_queue
迭代器会失效的:vector
是随机存取的:vector deque