1. 概述
STL::list是STL最常用的容器之一,其本质上是一个双向环状链表,链表每一个结点内容如下:
template
struct __list_node {
typedef void* void_pointer;
void_pointer next; // 指向下一个节点的指针
void_pointer prev; // 指向前一个节点的指针
T data; //list 数据
};
由于其双链表的结构,因此list适合需要频繁插入和删除数据的场合,这个和vector刚好相反。

2. API

Member functions
(constructor)    Construct list (public member function)
(destructor)    List destructor (public member function)
operator=    Copy container content (public member function)

Iterators:
begin    Return iterator to beginning (public member function)
end    Return iterator to end (public member function)
rbegin    Return reverse iterator to reverse beginning (public member function)
rend    Return reverse iterator to reverse end (public member function)

Capacity:
empty    Test whether container is empty (public member function)
size    Return size (public member function)
max_size    Return maximum size (public member function)
resize    Change size (public member function)

Element access:
front    Access first element (public member function)
back    Access last element (public member function)

Modifiers:
assign    Assign new content to container (public member function)
push_front    Insert element at beginning (public member function)
pop_front    Delete first element (public member function)
push_back    Add element at the end (public member function)
pop_back    Delete last element (public member function)
insert    Insert elements (public member function)
erase    Erase elements (public member function)
swap    Swap content (public member function)
clear    Clear content (public member function)

Operations:
splice    Move elements from list to list (public member function)
remove    Remove elements with specific value (public member function)
remove_if    Remove elements fulfilling condition (public member function template)
unique    Remove duplicate values (member function)
merge    Merge sorted lists (public member function)
sort    Sort elements in container (public member function)
reverse    Reverse the order of elements (public member function)

Allocator:
get_allocator    Get allocator (public member function)

Member types
of template > class list;
member type    definition
reference    Allocator::reference
const_reference    Allocator::const_reference
iterator    Bidirectional iterator
const_iterator    Constant bidirectional iterator
size_type    Unsigned integral type (usually same as size_t)
difference_type    Signed integral type (usually same as ptrdiff_t)
value_type    T
allocator_type    Allocator
pointer    Allocator::pointer
const_pointer    Allocator::const_pointer
reverse_iterator    reverse_iterator
const_reverse_iterator    reverse_iterator

3. 内存分配
相比于vector,list内存分配策略简单,每插入一个新元素,则new一个新结点,删除一个元素,则delete这个结点。需要注意的是,由于list的每一个结点除了包含对应的数据,还包含指向上一个和下一个元素的指针,因此,在资源紧张的环境下,这块占用的内存需要考虑。
list和vector占用内存对比:
如下程序:


对比程序消耗的内存,会发现在数据对象本身比较小的情况下,list额外消耗还是比较恐怖的。

4. list使用范例
list插入、删除、遍历操作

5. list有趣的API
1)splice
void splice ( iterator position, list& x );
void splice ( iterator position, list& x, iterator i );
void splice ( iterator position, list& x, iterator first, iterator last );
splice可以将一个list的元素搬到另一个list,避免了先删后插的做法,在数据元素比较大的情况下,还是相当高效的。
splice提供多个接口,可以搬移单个元素,部分元素or整个list

示例:

2)remove & remove_if
void remove ( const T& value );

template
void remove_if ( Predicate pred );

remove删除list中所有值为value的数据;
remove_if删除Predicate pred返回为真的元素,pred可以为函数或者类

6. list使用注意

1)list::size()时间复杂度
SGI list::size()源码:
size_type size() const {
  size_type __result = 0;
  distance(begin(), end(), __result);
  return __result;
}
注意,不是直接返回一个值,而是使用了distance(begin(), end(), __result);因此,推测其复杂度为0(n).写一个程序测试下:

 

在win7,VS2010下,输出:
37
38

linux 2.6.9 gcc 3.4.5,输出:
0
104900000


并不是所有编译器下size的实现都是通过distance得到,vs对这部分实现做了优化。

2)list迭代器失效
由于list本质是一个双向链表,所以,增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。
list删除元素时正确的写法:



崩溃写法

7. 总结

list本质是一个双向环形链表,所以其不能随机访问一个元素。在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。list可以动态增加或减少元素,内存管理自动完成。


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐