List使用一个doubly linked list(双向对列)来保存元素,相较于Vector的线性空间,List就显的复杂的多,它的好处是每次插入或删除一个元素,就配置或释放一个元素空间。对于任何位置的元素的插入或删除,List永远是常数时间。node
list自己和list节点是不一样的结构,须要分开设计。如下是STL list的节点(node)结构:c++
template <class T> struct __list_node{ typedef void* void_pointer; void_pointer prev; void_pointer next; T data; }
因为STL List是一个双向链表,迭代器必须具有前移、后移的能力,因此list提供的是Bidirectional Iterators
list 有一个重要的性质:插入操做(insert)和接合操做(splice)都不会形成原有list迭代器失效。这在vector是不成立的,由于vector的插入操做可能会形成空间的从新配置,致使原有迭代器的所有失效。甚至list的删除(erase)操做也只有“指向被删除元素”的那个迭代器失效,其余迭代器不收任何影响。数据结构
如下是list迭代器的设计:(只列出部分)函数
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 bidirectioanal_iterator_tag iterator_category; typedef T value_type; typedef Ptr pointer; typedef Ref referrence; typedef __list_node<T>* link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; link_type node; __list_iterator(link_type x):node(x); __list_iterator(){} __list_iterator(const iterator& x):node(x.node){} self& operator++() { node=(link_type)((*node).next); return *this; } self operator++(int) { self tmp=*this; ++*this; return tmp; } self& operator--() { node=(link_type)((*node).prev); return *this; } self operator--(int) { self tmp=*this; --*this; return tmp; } }
SGI list 不只是一个双向链表,并且仍是一个环装双向链表。因此它只须要一个指针,即可以完整表现整个链表:post
template <class T,class alloc=Alloc> class list{ protected: typedef list_node<T> node; public: typedef list_node* link_type; protected: link_type node; } iterator begin(){ return (link_type)((node*).next);} //return link_type,使用iterator(link_type)构造函数返回一个iterator; 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())}
list缺省使用alloc做为空间配置器,并据此另外定义了一个list_node_allocator.this
template <class T,class Alloc=alloc> class list{ protected: typedef __list_node<T> list_node; typedef simple_alloc<list_node,Alloc> list_node_allocator; }
list_node_allocator(n)表示配置n个节点空间。如下四个函数分别用来配置、释放、构造、销毁一个节点:设计
protected: //配置一个节点并传回 link_type get_node() {return list_node_allocator::allocate();} //释放一个节点 void put_node(lingk_type p){ list_node_allocator::deallocate();} //产生(配置并构造)一个节点,带有元素值 link_type create_node(const T& x){ link_type p=get_node(); construct(&p->data,x); retrurn p; } //销毁(析构并释放)一个节点 void destroy_node(link_type p){ destory(&p->data); put_data(p); } public: list(){ empty_initialize(); } protected: void empty_initialize(){ node=get_node(); node_next=node; node_prev=node; } void push_back(const T&) {insert(end(),x);} iterator insert(iterator position,const T& x){ link_type tmp=create_node(x);//产生一个节点; tmp->next=position.node; tmp->prev=position.node->prev; (link_type(psition.node->prev))->next=tmp; postion.node->prev=tmp; return tmp; }
void push_back(const T& x){insert(end(),x);} void psuh_pront(const T& x){insert(begin(),x);} //移除迭代器position所指节点 iterator erase(iterator position){ link_type next_node=link_type(position.node->next); link_type prev_node=link_type(position.node->prev); prev_node->next=next_node; next_node->prev=prev_node; destroy_node(position.node); return iterator(next_node); } //移除头结点 void pop_front() { erase(begin());} //移除尾节点 void pop_back(){ iterator tmp=end(); erase(--tmp); } //清除全部节点(整个链表) template<class T,class Alloc> void list<T,Alloc>::clear(){ link_type cur=(link_type)node->next; while(cur!=node){ link_type tmp=cur; cur=(link_type)cur->next; destroy(tmp); } node->next=node; node->prev=node; } //将数值为value的全部元素移除 template <class T,class Alloc> void list<T,Alloc>::remove(const T& value){ iterator first=begin(); iterator last=end(); while(first!=last){ iterator next = first; ++next; if(*first==next) erase(first); first=next; } } //移除数值相同的连续元素 template <class T,class Alloc> void list<T,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; } }