相较于vector的连续线性空间,list就显得复杂很多,它的好处是每次插入或删除一个元素,就配置或释放一个元素的空间。因此,list对空间的运用有绝对的精确,一点也不浪费。而且,对于任何位置的元素插入和元素移除,list永远是常数时间。
list的节点结构:
template
struct __list_node
{
typedef void* void_pointer;
void_pointer prev;
void_pointer next;
T data;
}
list的迭代器:
list不再能够像vector一样以普通指针作为迭代器,因为其节点不保证在存储空间中连续存在。list迭代器必须有能力指向list的节点,并有能力进行正确的递增、递减、取值、成员存取等操作。由于STL list是一个双向链表,迭代器必须具备前移、后移的能力,所以list提供的是Bidirectional Iterators。list有一个重要性质:插入操作和结合操作都不会造成原有的list迭代器失效,甚至list的元素删除操作也只有“指向被删除元素”的那个迭代器失效,其他迭代器不受任何影响。
list的数据结构:
SGI list不仅是一个双向链表,而且还是一个环状双向链表。所以它只需要一个指针,便可以完整表现整个链表:
template
class list
{
protected:
typedef __list_node list_node;
public:
typedef list_node* link_type;
protected:
link_type node;
...
};
如果让指针node指向刻意置于尾端的一个空白节点,node便能符合STL对于“前开后闭”区间的要求,成为last迭代器。
2.1构造函数:
/// Creates an empty list.
list();
/// Creates a list with n elements, each of which is a copy of T().
list(size_type n);
/// Creates a list with n copies of t.
list(size_type n, const T& t);
/// The copy constructor.
list(const list&);
/// Creates a list with a copy of a range.
template list(InputIterator f, InputIterator l);
2.2析构函数:
/// The destructor.
~list();
2.3插入元素:
/// Inserts a new element at the beginning.
void push_front(const T&);
/// Inserts a new element at the end.
void push_back(const T&);
/// Inserts x before pos.
iterator insert(iterator pos, const T& x);
/// Inserts the range [f, l) before pos.
template void insert(iterator pos, InputIterator f, InputIterator l);
/// Inserts n copies of x before pos.
void insert(iterator pos, size_type n, const T& x);
2.4删除元素:
/// Removes the first element.
void pop_front();
/// Removes the last element.
void pop_back();
/// Erases the element at position pos.
iterator erase(iterator pos);
/// Erases the range [first, last)
iterator erase(iterator first, iterator last);
/// 删除指定数值元素
void remove(const T& value);
/// 移除数值相同的连续元素
void unique();
/// Erases all of the elements.
void clear();
2.5返回元素指针或元素:
/// Returns an iterator pointing to the beginning of the list.
iterator begin();
/// Returns an iterator pointing to the end of the list.
iterator end();
/// Returns a reverse_iterator pointing to the beginning of the reversed list.
reverse_iterator rbegin();
/// Returns a reverse_iterator pointing to the end of the reversed list.
reverse_iterator rend();
/// Returns the first element.
reference front();
/// Returns the last element.
reference back();
2.6其他:
/// Returns the size of the list.
size_type size() const;
/// Returns the largest possible size of the list.
size_type max_size() const;
/// true if the list's size is 0.
bool empty() const;
/// 容器拼接
void splice(iterator pos, list& L);
void splice(iterator pos, list& L, iterator i);
void splice(iterator pos, list& L, iterator f, iterator l);
/// 元素排序
void sort();
/// 容器合并
void merge(list& L);
/// 容器内容逆向重置
void reverse();
#include
#include
#include
int main()
{
typedef std::list ILIST;
/// 1.实例对象
ILIST first; // empty
ILIST second(5); // 0 0 0 0 0
ILIST third(5,10); // 10 10 10 10 10
ILIST fourth(third); // 10 10 10 10 10
ILIST fifth(third.begin(),third.end()); // 10 10 10 10 10
/// 2.插入元素
ILIST::iterator ilitr;
ILIST ilist;
/// 2.1尾部插入元素
ilist.push_back(1);
ilist.push_back(2);
ilist.push_back(3); // 1 2 3
/// 2.2头部插入元素
ilist.push_front(8);
ilist.push_front(16); // 16 8 1 2 3
/// 2.3指定位置插入元素
ilitr = find(ilist.begin(),ilist.end(),1);
if(ilitr != ilist.end())
ilist.insert(ilitr,4); // 16 8 4 1 2 3
/// 3.删除元素
/// 3.1删除头部元素
ilist.pop_front(); // 8 4 1 2 3
/// 3.2删除尾部元素
ilist.pop_back(); // 8 4 1 2
/// 3.3删除指定位置元素
ilitr = find(ilist.begin(),ilist.end(),1);
if(ilitr != ilist.end())
ilist.erase(ilitr); // 8 4 2
/// 3.4删除指定数值元素
ilist.remove(8); // 4 2
/// 3.5移除数值相同的连续元素
ilist.push_back(3);
ilist.push_back(3);
ilist.push_back(4); // 4 2 3 3 4
ilist.unique(); // 4 2 3 4
/// 3.6清空所有元素
ilist.clear(); // empty
/// 4.访问元素
ilist.push_back(1);
ilist.push_back(2);
ilist.push_back(4);
/// 4.1访问头部元素
ilist.front(); // 1
/// 4.2访问尾部元素
ilist.back(); // 4
/// 5.其他
/// 5.1容器尺寸
ilist.size(); // 3
/// 5.2容器最大尺寸
ilist.max_size(); // 768614336404564650
/// 5.3容器是否为空
ilist.empty(); // 0
/// 5.4容器拼接
ILIST oilist;
oilist.push_back(3);
ilitr = find(ilist.begin(),ilist.end(),4);
ilist.splice(ilitr,oilist); // 1 2 3 4
/// 5.5容器合并
oilist.push_back(12);
oilist.push_back(6);
oilist.push_back(9);
oilist.sort();
/// 两个lists的内容都必须先经过递增排序
ilist.merge(oilist); // 1 2 3 4 6 9 12
/// 5.6容器内容逆向重置
ilist.reverse(); // 12 9 6 4 3 2 1
return 0;
}
本文内容摘录于《STL源码剖析》