list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
list的底层是双向链表结构,双向链表中每个元素存储在互不相关的节点中,在节点中通过指针指向其前一个元素和后一个元素。
list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
下面正式进入List的学习。
一、list结构剖析
list 是一个双向循环链表
结点类:
template<class T>
struct list_node // 节点
{
T _data;
list_node<T>* _next;
list_node<T>* _prev;
list_node(const T& x = T())
: _data(x)
, _next(nullptr)
, _prev(nullptr)
{}
};
迭代器类:
template<class T, class Ref, class Ptr>
struct __list_iterator
{
typedef list_node<T> Node;
typedef __list_iterator<T, Ref, Ptr> iterator;
Node* _node;
//.....
};
list 类:
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
//......
private:
Node* _head;
};
list类中包含上面两个类。
二、List 的使用
下面介绍list常用接口的使用。
2.1 list的构造
void list_test1()
{
list<int> l1; // 构造空的l1
list<int> l2(4, 100);