STL源码阅读(七) (SGI STL v3.3)
stl_set.h (<set>)
set使用红黑树实现,每个键值都不相同,且按序存储。注意operator=(即_Rb_tree的实现)
先销毁赋值号左边的set,
然后将右边的set拷贝给左边的set, 而不是原值替换。
set的所有函数都是用_Rb_tree的函数实现的,相当于_Rb_tree的一个包装类。
stl_multiset.h (<set>)
multiset使用红黑树实现,键值可重复,按序存储。相当于_Rb_tree的一个包装类。
stl_map.h (<map>)
使用红黑树实现,键值不可重复,按键值顺序排序。相当于_Rb_tree的一个包装类。
注意:嵌套类value_compare
实际比较的还是键值。
stl_multimap.h (<map>)
使用红黑树实现,和map
基本相同,只不过是可以重复相同的键值。
stl_slist.h (<forward_list> C++11)
和list
相比,实现方式不同,list
通过双向环状链表实现,而slist
使用单向链表实现。另外,slist
的
迭代器类型是前向迭代器,和list
的双向迭代器相比更加节省内存。不足之处是slist
不支持元素的快速随机访问。
// slist结点
struct _Slist_node_base
{
_Slist_node_base* _M_next;
};
template <class _Tp>
struct _Slist_node : public _Slist_node_base
{
_Tp _M_data;
};
// slist内存分配器
// 在创建链表时,多分配一个结点(_M_head)用于指向整个链表。
// slist迭代器,前向迭代器,只有++这一个单步方向
// 归并排序
template <class _Tp, class _Alloc>
void slist<_Tp,_Alloc>::sort()
{
if (this->_M_head._M_next && this->_M_head._M_next->_M_next) {
slist __carry;
slist __counter[64];
int __fill = 0;
while (!empty()) {
__slist_splice_after(&__carry._M_head,
&this->_M_head, this->_M_head._M_next);
int __i = 0;
while (__i < __fill && !__counter[__i].empty()) {
__counter[__i].merge(__carry);
__carry.swap(__counter[__i]);
++__i;
}
__carry.swap(__counter[__i]);
if (__i == __fill)
++__fill;
}
for (int __i = 1; __i < __fill; ++__i)
__counter[__i].merge(__counter[__i-1]);
this->swap(__counter[__fill-1]);
}
}
// 其它函数看看参考手册,了解其功能就能知道其怎么实现的了,没什么好说的了。