list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构
list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构
list源码2(参考STL源码--侯捷):constructor、push_back、insert
list源码3(参考STL源码--侯捷):push_front、push_back、erase、pop_front、pop_back、clear、remove、unique
list源码4(参考STL源码--侯捷):transfer、splice、merge、reverse、sort
list概述
list相对于vector复杂得多,list是一个双链表,对于插入元素、删除元素,list都相对比较简单
list节点
template <class T>
struct __list_node{
typedef void* void_pointer;
void_pointer prev; //类型为void*,其实也可以设置为__list_node<T>*
void_pointer next;
T data;
};
list迭代器
list迭代器必须有能力指向list的节点,并有能力进行正确的递增、递减、取值、成员存取等操作,同时list是双向链表,迭代器必须具备前移、后移的能力,所以list提供的是Bidirectional Iterators。
list有一个重要性质:插入(insert)操作和接合(splice)操作都不会造成原有的list迭代器失效,甚至list的元素删除(erase)操作也只有“指向被删除元素”的那个迭代器失效,其它迭代器失效不受任何影响。
template<class T,class Ref,class Ptr> struct __list_iterator{ typedef __list_iterator<T,T&,T*> iterator; typedef __list_iterator<T,Ref,Ptr> self; typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef __list_node<T>* link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; link_type node; //迭代器内部需要一个普通指针,指向list的节点 //constructor __list_iterator(link_type x):node(x){} __list_iterator(){} __list_iterator(const iterator& x):node(x.node){} bool operator ==(const self& x)const{return node==x.node;} bool operator !=(const self& x)const{return node!=x.node;} //以下对迭代器取值,取的是节点的数据值 reference operator->() const{return &(operator*());} //对迭代器累加 self& operator++(){ node=(link_type)((*node).next); return *this; } self operator++(int){ self tmp=*this; ++*this; return tmp; } //对迭代器减1 self& operator--(){ node=(link_type)((*node).prev); return *this; } self operator--(int){ self tmp=*this; --*this; return tmp; } };
list数据结构
list不仅是一个双向链表,而且还是一个环状双向链表,所以它只需要便可以完整表现整个链表:
template <class T,class Alloc=alloc> //缺省使用alloc为适配器 class list{ protected: typedef __list_node<T> list_node; public: typedef list_node* link_type; protected: link_type node; //只要一个指针,便可表示整个环装双向链表 ...... };
如果让node(如上)指向刻意置于尾端的一个空间节点,node便能符合STL对于“前闭后开”区间的要求,成为last迭代器,如下图,这样以来,以下几个函数可以很好完成:
iterator begin(){return (link_type)((*node).next);} iterator end(){return node;} bool empty() const{return node->next==node;} size_type size() const{ size_type result=0; distance(begin(),end(),result); return result; } //取头结点的内容 reference front(){return *begin();} //取尾节点的内容 reference back(){return *(--end());}