template < class T, class Alloc = allocator<T> >
class list;
list是一个序列容器,运行在任何位置进行常数时间插入和删除操作,并且可以双向迭代。list容器使用双向循环链表实现,与其他序列容器(array,vector,和deque)相比,list在指定位置插入,抽取,和移动元素表现更好,时间复杂度为O(1);当访问指定位置的元素效率较低,时间复杂度为O(n)。
使用只需包含list/list.h,SGI将其实现在stl_list.h。
具体实现如下:
list节点类定义
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迭代器类
struct _List_iterator_base {
typedef size_t size_type; //大小类型
typedef ptrdiff_t difference_type; //指针差类型
typedef bidirectional_iterator_tag iterator_category; //双向迭代器类型
_List_node_base* _M_node;
_List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
_List_iterator_base() {}
void _M_incr() { _M_node = _M_node->_M_next; }
void _M_decr() { _M_node = _M_node->_M_prev; }
bool operator==(const _List_iterator_base& __x) const {
return _M_node == __x._M_node;
}
bool operator!=(const _List_iterator_base& __x) const {
return _M_node != __x._M_node;
}
};
template<class _Tp, class _Ref, class _Ptr>
struct _List_iterator : public _List_iterator_base {
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
typedef _List_iterator<_Tp,_Ref,_Ptr> _Self;
typedef _Tp value_type;
typedef _Ptr pointer;
typedef _Ref reference;
typedef _List_node<_Tp> _Node;
_List_iterator(_Node* __x) : _List_iterator_base(__x) {}
_List_iterator() {}
_List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}
reference operator*() const { return ((_Node*) _M_node)->_M_data; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
_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;
}
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
inline bidirectional_iterator_tag
iterator_category(const _List_iterator_base&)
{
return bidirectional_iterator_tag();
}
template <class _Tp, class _Ref, class _Ptr>
inline _Tp*
value_type(const _List_iterator<_Tp, _Ref, _Ptr>&)
{
return 0;
}
inline ptrdiff_t*
distance_type(const _List_iterator_base&)
{
return 0;
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
list模板类实现
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class list : protected _List_base<_Tp, _Alloc> {
...
}
- 型别定义
typedef _List_base<_Tp, _Alloc> _Base;
protected:
typedef void* _Void_pointer; //空指针类型
public:
typedef _Tp value_type; //值类型
typedef value_type* pointer; //指针类型
typedef const value_type* const_pointer; //常量指针类型
typedef value_type& reference; //引用类型
typedef const value_type& const_reference; //常量引用
typedef _List_node<_Tp> _Node; //链表节点类型
typedef size_t size_type; //大小类型
typedef ptrdiff_t difference_type; //指针差类型
typedef typename _Base::allocator_type allocator_type; //空间配置器类型
allocator_type get_allocator() const { return _Base::get_allocator(); } //返回空间配置器
public:
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; //迭代器类型
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; //常量迭代器类型
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
typedef reverse_bidirectional_iterator<const_iterator,value_type,
const_reference,difference_type>
const_reverse_iterator; //
typedef reverse_bidirectional_iterator<iterator,value_type,reference,
difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
构造器
默认构造器
explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {}
填充构造器
list(size_type __n, const _Tp& __value,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ insert(begin(), __n, __value); } //头插
explicit list(size_type __n)
: _Base(allocator_type())
{ insert(begin(), __n, _Tp()); }
范围构造器
#ifdef __STL_MEMBER_TEMPLATES
// We don't need any dispatching tricks here, because insert does all of
// that anyway.
template <class _InputIterator>
list(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ insert(begin(), __first, __last); } //头插
#else /* __STL_MEMBER_TEMPLATES */
list(const _Tp* __first, const _Tp* __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ this->insert(begin(), __first, __last); }
list(const_iterator __first, const_iterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{ this->insert(begin(), __first, __last); }
#endif /* __STL_MEMBER_TEMPLATES */
拷贝构造器
list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator())
{ insert(begin(), __x.begin(), __x.end()); } //头插
- 析构器
~list() { } //析构函数,什么都不需要做
- 拷贝赋值运算符
template <class _Tp, class _Alloc>
list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x)
{
if (this != &__x) { //防止自赋值
iterator __first1 = begin();
iterator __last1 = end();
const_iterator __first2 = __x.begin();
const_iterator __last2 = __x.end();
while (__first1 != __last1 && __first2 != __last2) //遍历依次赋值
*__first1++ = *__first2++;
if (__first2 == __last2) //多出元素删除
erase(__first1, __last1);
else //少了元素插入
insert(__last1, __first2, __last2);
}
return *this;
}
- 迭代器
iterator begin() { return (_Node*)(_M_node->_M_next); }
const_iterator begin() const { return (_Node*)(_M_node->_M_next); }
iterator end() { return _M_node; }
const_iterator end() const { return _M_node; }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(end()); }
reverse_iterator rend()
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(begin()); }
- 容量
bool empty() const { return _M_node->_M_next == _M_node; } //判断链表是否为空
size_type size() const { //返回链表的大小
size_type __result = 0;
distance(begin(), end(), __result); //头尾迭代器间距离即为链表大小
return __result;
}
size_type max_size() const { return size_type(-1); } //链表可分配的最大值
- 元素访问
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(--end()); }
const_reference back() const { return *(--end()); }
- 修改器
assign
void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
void _M_fill_assign(size_type __n, const _Tp& __val);
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
iterator __i = begin();
for ( ; __i != end() && __n > 0; ++__i, --__n) //遍历赋值
*__i = __val;
if (__n > 0) //少了元素则插入
insert(end(), __n, __val);
else //多出元素则删除
erase(__i, end());
}
接受迭代器版本,要判读是否是整数,再调用不同的函数。
#ifdef __STL_MEMBER_TEMPLATES
template <class _InputIterator>
void assign(_InputIterator __first, _InputIterator __last) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_assign_dispatch(__first, __last, _Integral()); //根据是否是整数分发给不同函数
}
template <class _Integer>
void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
{ _M_fill_assign((size_type) __n, (_Tp) __val); } //是整数
template <class _InputIterator>
void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type);
#endif /* __STL_MEMBER_TEMPLATES */
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
iterator __i = begin();
for ( ; __i != end() && __n > 0; ++__i, --__n)
*__i = __val;
if (__n > 0)
insert(end(), __n, __val);
else
erase(__i, end());
}
#ifdef __STL_MEMBER_TEMPLATES
template <class _Tp, class _Alloc> template <class _InputIter>
void
list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2,
__false_type)
{
iterator __first1 = begin();
iterator __last1 = end();
for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
*__first1 = *__first2;
if (__first2 == __last2)
erase(__first1, __last1);
else
insert(__last1, __first2, __last2);
}
push pop
void push_front(const _Tp& __x) { insert(begin(), __x); } //头部插入
void push_front() {insert(begin());}
void push_back(const _Tp& __x) { insert(end(), __x); } //尾部插入
void push_back() {insert(end());}
void pop_front() { erase(begin()); } //删除头部元素
void pop_back() { //删除尾部元素
iterator __tmp = end(); //end()指向的节点不能访问,只是作为一个结尾标志
erase(--__tmp); //实际删除尾部前面一个元素
}
insert
同样考虑迭代器版本是否为整数。
iterator insert(iterator __position, const _Tp& __x) { //指定位置插入元素
_Node* __tmp = _M_create_node(__x); //创建一个节点
__tmp->_M_next = __position._M_node; //调整指针
__tmp->_M_prev = __position._M_node->_M_prev;
__position._M_node->_M_prev->_M_next = __tmp;
__position._M_node->_M_prev = __tmp;
return __tmp;
}
iterator insert(iterator __position) { return insert(__position, _Tp()); }
void insert(iterator __pos, size_type __n, const _Tp& __x)
{ _M_fill_insert(__pos, __n, __x); }
void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x);
template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::_M_fill_insert(iterator __position,
size_type __n, const _Tp& __x)
{
for ( ; __n > 0; --__n)
insert(__position, __x);
}
#ifdef __STL_MEMBER_TEMPLATES
// Check whether it's an integral type. If so, it's not an iterator.
template<class _Integer>
void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
__true_type) {
_M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
}
template <class _InputIterator>
void _M_insert_dispatch(iterator __pos,
_InputIterator __first, _InputIterator __last,
__false_type);
template <class _InputIterator>
void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_insert_dispatch(__pos, __first, __last, _Integral());
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator __position, const _Tp* __first, const _Tp* __last);
void insert(iterator __position,
const_iterator __first, const_iterator __last);
#endif /* __STL_MEMBER_TEMPLATES */
#ifdef __STL_MEMBER_TEMPLATES
template <class _Tp, class _Alloc> template <class _InputIter>
void
list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position,
_InputIter __first, _InputIter __last,
__false_type)
{
for ( ; __first != __last; ++__first)
insert(__position, *__first);
}
#else /* __STL_MEMBER_TEMPLATES */
template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::insert(iterator __position,
const _Tp* __first, const _Tp* __last)
{
for ( ; __first != __last; ++__first)
insert(__position, *__first);
}
template <class _Tp, class _Alloc>
void
list<_Tp, _Alloc>::insert(iterator __position,
const_iterator __first, const_iterator __last)
{
for ( ; __first != __last; ++__first)
insert(__position, *__first);
}
#endif /* __STL_MEMBER_TEMPLATES */
erase
iterator erase(iterator __position) { //删除指定位置元素
_List_node_base* __next_node = __position._M_node->_M_next;
_List_node_base* __prev_node = __position._M_node->_M_prev;
_Node* __n = (_Node*) __position._M_node;
__prev_node->_M_next = __next_node;
__next_node->_M_prev = __prev_node;
_Destroy(&__n->_M_data); //析构元素
_M_put_node(__n); //释放节点空间
return iterator((_Node*) __next_node); //返回删除节点下一个节点位置
}
iterator erase(iterator __first, iterator __last);
template <class _Tp, class _Alloc>
typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first,
iterator __last)
{
while (__first != __last) //遍历删除
erase(__first++);
return __last;
}
swap
void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); } //调用全局交换函数
template <class _Tp, class _Alloc>
inline void
swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) //非成员函数版
{
__x.swap(__y); //调用了成员函数
}
resize
void resize(size_type __new_size, const _Tp& __x);
void resize(size_type __new_size) { this->resize(__new_size, _Tp()); }
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x)
{
iterator __i = begin();
size_type __len = 0;
for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
;
if (__len == __new_size)
erase(__i, end());
else // __i == end()
insert(end(), __new_size - __len, __x);
}
clear
void clear() { _Base::clear(); }
template <class _Tp, class _Alloc>
void
_List_base<_Tp,_Alloc>::clear()
{
_List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next;
while (__cur != _M_node) { //遍历list,依次进行析构,释放空间操作
_List_node<_Tp>* __tmp = __cur;
__cur = (_List_node<_Tp>*) __cur->_M_next;
_Destroy(&__tmp->_M_data);
_M_put_node(__tmp);
}
_M_node->_M_next = _M_node;
_M_node->_M_prev = _M_node;
}
- 操作
splice
void splice(iterator __position, list& __x) { //将链表__x拼接到__position之前
if (!__x.empty())
this->transfer(__position, __x.begin(), __x.end());
}
void splice(iterator __position, list&, iterator __i) { //将链表中__i节点拼接到__position之前
iterator __j = __i;
++__j;
if (__position == __i || __position == __j) return;
this->transfer(__position, __i, __j);
}
void splice(iterator __position, list&, iterator __first, iterator __last) {
if (__first != __last)
this->transfer(__position, __first, __last);
}
void transfer(iterator __position, iterator __first, iterator __last) { //将[__first,__last)中的元素转移到__position之前,注意转移的两个链表可以是同一个链表
if (__position != __last) { //当是同一个链表时,如果__position==__last,则不需要转移
// Remove [first, last) from its old position.
__last._M_node->_M_prev->_M_next = __position._M_node;
__first._M_node->_M_prev->_M_next = __last._M_node;
__position._M_node->_M_prev->_M_next = __first._M_node;
// Splice [first, last) into its new position.
_List_node_base* __tmp = __position._M_node->_M_prev;
__position._M_node->_M_prev = __last._M_node->_M_prev;
__last._M_node->_M_prev = __first._M_node->_M_prev;
__first._M_node->_M_prev = __tmp;
}
}
remove
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::remove(const _Tp& __value) //删除链表中值为__value的节点
{
iterator __first = begin();
iterator __last = end();
while (__first != __last) {
iterator __next = __first;
++__next;
if (*__first == __value) erase(__first);
__first = __next;
}
}
remove_if
template <class _Tp, class _Alloc> template <class _Predicate>
void list<_Tp, _Alloc>::remove_if(_Predicate __pred) //一元仿函数做参数
{
iterator __first = begin();
iterator __last = end();
while (__first != __last) {
iterator __next = __first;
++__next;
if (__pred(*__first)) erase(__first);
__first = __next;
}
}
unique
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::unique() //删除掉重复元素
{
iterator __first = begin();
iterator __last = end();
if (__first == __last) return;
iterator __next = __first;
while (++__next != __last) {
if (*__first == *__next) //找到则删除
erase(__next);
else
__first = __next;
__next = __first;
}
}
template <class _Tp, class _Alloc> template <class _BinaryPredicate>
void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) //二元仿函数做参数
{
iterator __first = begin();
iterator __last = end();
if (__first == __last) return;
iterator __next = __first;
while (++__next != __last) {
if (__binary_pred(*__first, *__next))
erase(__next);
else
__first = __next;
__next = __first;
}
}
merge
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) //将链合并到*this上,注意调用此函数必须保证两个链表事先经过递增排序
{
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
while (__first1 != __last1 && __first2 != __last2)
if (*__first2 < *__first1) { //小于则插到目标链表前面
iterator __next = __first2;
transfer(__first1, __first2, ++__next);
__first2 = __next;
}
else //否则迭代下一个节点
++__first1;
if (__first2 != __last2) transfer(__last1, __first2, __last2); //还有元素,则放在后面,即放在end()节点前面
}
template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x,
_StrictWeakOrdering __comp) //接受二元仿函数做参数
{
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first2, *__first1)) {
iterator __next = __first2;
transfer(__first1, __first2, ++__next);
__first2 = __next;
}
else
++__first1;
if (__first2 != __last2) transfer(__last1, __first2, __last2);
}
sort
由于list不提供随机访问迭代器,所以不能使用全局的sort算法,所以要自己实现。
使用的是归并排序的迭代实现,侯捷的数上写的是快速排序是错误的。具体可以参考这篇博客:https://sosohu.github.io/algorithm/2015/04/14/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F%E7%9A%84%E8%BF%AD%E4%BB%A3%E5%86%99%E6%B3%95.html
https://stackoverflow.com/questions/6728580/what-makes-the-gcc-stdlist-sort-implementation-so-fast
template <class _Tp, class _Alloc>
void list<_Tp, _Alloc>::sort()
{
// Do nothing if the list has length 0 or 1.
if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { //链表长度为0或1不用考虑排序
list<_Tp, _Alloc> __carry;
list<_Tp, _Alloc> __counter[64]; //2^0,2^1,2^2,...,2^(64-1),最多可以排序2^63个元素
int __fill = 0;
while (!empty()) { //依次取出链表中元素
__carry.splice(__carry.begin(), *this, begin()); //依次抽取元素到__carry中
int __i = 0;
while(__i < __fill && !__counter[__i].empty()) {
__counter[__i].merge(__carry);
__carry.swap(__counter[__i++]);
}
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
}
for (int __i = 1; __i < __fill; ++__i)
__counter[__i].merge(__counter[__i-1]);
swap(__counter[__fill-1]);
}
}
template <class _Tp, class _Alloc> template <class _StrictWeakOrdering>
void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
{
// Do nothing if the list has length 0 or 1.
if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
list<_Tp, _Alloc> __carry;
list<_Tp, _Alloc> __counter[64];
int __fill = 0;
while (!empty()) {
__carry.splice(__carry.begin(), *this, begin());
int __i = 0;
while(__i < __fill && !__counter[__i].empty()) {
__counter[__i].merge(__carry, __comp);
__carry.swap(__counter[__i++]);
}
__carry.swap(__counter[__i]);
if (__i == __fill) ++__fill;
}
for (int __i = 1; __i < __fill; ++__i)
__counter[__i].merge(__counter[__i-1], __comp);
swap(__counter[__fill-1]);
}
}
reverse
inline void __List_base_reverse(_List_node_base* __p) //将*this内容逆向重置
{
_List_node_base* __tmp = __p;
do {
__STD::swap(__tmp->_M_next, __tmp->_M_prev);
__tmp = __tmp->_M_prev; // Old next node is now prev.
} while (__tmp != __p);
}
template <class _Tp, class _Alloc>
inline void list<_Tp, _Alloc>::reverse()
{
__List_base_reverse(this->_M_node);
}
- 关系运算符
template <class _Tp, class _Alloc>
inline bool
operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) //重载==运算符
{
typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
const_iterator __end1 = __x.end();
const_iterator __end2 = __y.end();
const_iterator __i1 = __x.begin();
const_iterator __i2 = __y.begin();
while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
++__i1;
++__i2;
}
return __i1 == __end1 && __i2 == __end2;
}
template <class _Tp, class _Alloc>
inline bool operator<(const list<_Tp,_Alloc>& __x,
const list<_Tp,_Alloc>& __y) //重载<运算符
{
return lexicographical_compare(__x.begin(), __x.end(),
__y.begin(), __y.end());
}
#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
template <class _Tp, class _Alloc>
inline bool operator!=(const list<_Tp,_Alloc>& __x,
const list<_Tp,_Alloc>& __y) { //重载!=运算符
return !(__x == __y);
}
template <class _Tp, class _Alloc>
inline bool operator>(const list<_Tp,_Alloc>& __x,
const list<_Tp,_Alloc>& __y) { //重载>运算符
return __y < __x;
}
template <class _Tp, class _Alloc>
inline bool operator<=(const list<_Tp,_Alloc>& __x,
const list<_Tp,_Alloc>& __y) { //重载<=运算符
return !(__y < __x);
}
template <class _Tp, class _Alloc>
inline bool operator>=(const list<_Tp,_Alloc>& __x,
const list<_Tp,_Alloc>& __y) { //重载>=运算符
return !(__x < __y);
}
参考:侯捷《STL源码剖析》
http://www.cplusplus.com/reference/list/list/