STL源码阅读(七)

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]);
  }
}

// 其它函数看看参考手册,了解其功能就能知道其怎么实现的了,没什么好说的了。

参考资料

  1. sgi STL
  2. cppreference.com
posted @ 2016-08-06 10:26  corfox  阅读(254)  评论(0编辑  收藏  举报