参考SGI STL 及 侯捷《STL源码剖析》
概述
STL的list是一个环状双向链表,链表尾端是一个空节点
list数据结构
list的节点使用prev指向前一个节点,next指向后一个节点,使用data来存数据
STL如下实现上述结构
//类似双向链表
struct _List_node_base {
_List_node_base* _M_next; //指向下一个节点
_List_node_base* _M_prev; //指向前一个节点
};
template <class _Tp>
struct _List_node : public _List_node_base {
_Tp _M_data; //存放数据
};
当list为空链表时,节点的prev和next均指向自己
_List_base(const allocator_type&) {
_M_node = _M_get_node();
_M_node->_M_next = _M_node;
_M_node->_M_prev = _M_node;
}
list的迭代器
list支持迭代器,其自增自减均是通过操作prev和next指针实现
void _M_incr() { _M_node = _M_node->_M_next; } //指向下一个节点
void _M_decr() { _M_node = _M_node->_M_prev; } //指向前一个节点
----------
//前置++
_Self& operator++() {
this->_M_incr();
return *this;
}
//后置++
_Self operator++(int) {
_Self __tmp = *this;
this->_M_incr();
return __tmp;
}
//前置--
_Self& operator--() {
this->_M_decr();
return *this;
}
//后置--
_Self operator--(int) {
_Self __tmp = *this;
this->_M_decr();
return __tmp;
}
list的操作
clear
通过从头开始遍历整个list,逐步将每个节点的数据destroy释放空间来完成整个链表的clear操作,最终恢复到空链表状态,即
push_front、push_bavoid transfer(iterator __position, iterator __first, iterator __last)ck、erase、pop_front、pop_back
通过调用迭代器的函数在相应位置完成链表的调整来实现- transfer、splice
将[__first,__last)内的所有元素移动到__position之前,splice调用transfer函数
void transfer(iterator __position, iterator __first, iterator __last)
- remove
//将值为__value的所有元素移除
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::remove(const _Tp& __value)
- unique
//移除数值相同的连续元素。注意,只有“连续而相同的元素”,才会被移除剩一个
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::unique()
- merge
//将__x合并到*this身上,两个lists的内容都必须先经过递增排序
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x)