STL Source Analysis (4): Container (list)

Source: Internet
Author: User

The list is much more complex than the continuous linear space of vectors, and the advantage is that each time an element is inserted or deleted, an element space is configured or freed. Therefore, the list of the use of space is absolutely accurate, not a waste. Also, for element insertion or element removal at any location, the list is always constant time.

The list internally is a doubly linked list, and the inner elements are chained together with each other, each of which knows its previous element and the position of the next element.

template <class T>struct __list_node {  typedefvoid* void_pointer;  void_pointer next;  void_pointer prev;  T data;};

The list node does not necessarily have to be in continuous space, so it cannot be used as a vector to make iterators with native pointers, and its iterators must implement actions such as moving forward, moving back, and taking values.
The list insert operation and the join operation do not invalidate the original list iterator, which is not true in vector. Because the insertion of a vector can cause memory reconfiguration, the original iterator is all invalidated. Even the element delete operation (erase) of the list, and only the iterator that points to the deleted element, is invalidated, and no other iterators are affected.
   
   

To see the source code:

Template<classTclassRef,classPtr>struct__list_iterator {typedef__list_iterator<t, T&amp, t*> iterator;typedef__list_iterator<t,ConstT&,ConstT*> const_iterator;typedef__list_iterator<t, Ref, ptr> self;typedefBidirectional_iterator_tag iterator_category;typedefT Value_type;typedefPTR pointer;typedefREF reference;typedef__list_node<t>* Link_type;typedefsize_t Size_type;typedefptrdiff_t Difference_type; Link_type node;//Internally keep a native pointer to the list node__list_iterator (Link_type x): node (x) {} __list_iterator () {} __list_iterator (Constiterator& x): node (x.node) {}BOOL operator==(Constself& x)Const{returnnode = = X.node; }BOOL operator!=(Constself& x)Const{returnNode! = X.node; } referenceoperator*()Const{return(*node). data; } self&operator+ + () {node = (Link_type) ((*node). Next);return* This; } Selfoperator++(int) {Self TMP = * This; ++* This;returntmp } self&operator--() {node = (Link_type) ((*node). prev);return* This; } Selfoperator--(int) {Self TMP = * This; --* This;returntmp }};Template<classTclassAlloc = alloc>class List{protected:typedef void* Void_pointer;typedef__list_node<t> List_node;typedefSimple_alloc<list_node, alloc> List_node_allocator; Public:typedef__list_iterator<t, T&amp, t*> iterator;typedef__list_iterator<t,ConstT&,ConstT*> const_iterator;protected: Link_type node;protected: Link_type Get_node () {returnList_node_allocator::allocate (); }voidPut_node (Link_type p) {list_node_allocator::d eallocate (P);} Link_type Create_node (Constt& x) {Link_type p = get_node ();    __stl_try {construct (&p->data, x); } __stl_unwind (Put_node (p));returnP }voidDestroy_node (Link_type p) {destroy (&p->data);  Put_node (P); }protected:voidEmpty_initialize () {node = Get_node ();    Node->next = node;  Node->prev = node; }voidFill_initialize (size_type N,Constt& value) {empty_initialize ();    __stl_try {Insert (begin (), n, value);  } __stl_unwind (Clear (); Put_node (node)); }protected://migrate elements within [first,last] to position  voidTransfer (iterator position, iterator first, iterator last) {if(Position! = last)      {(* (Link_type ((*last.node). prev)). Next = Position.node;      (* (Link_type ((*first.node). prev)). Next = Last.node;        (* (Link_type ((*position.node). prev)). Next = First.node;      Link_type tmp = Link_type ((*position.node). prev);      (*position.node). Prev = (*last.node). prev;       (*last.node). Prev = (*first.node). prev;    (*first.node). prev = tmp; }  } Public:voidSplice (iterator position,List& x) {if(!x.empty ()) Transfer (position, X.begin (), X.end ()); } Public:List() {empty_initialize ();} Iterator begin () {return(Link_type) ((*node). Next); } Const_iterator Begin ()Const{return(Link_type) ((*node). Next); } iterator End () {returnNode } Const_iterator End ()Const{returnNode }BOOLEmpty ()Const{returnNode->next = = node; } size_type Size ()Const{Size_type result =0; Distance (begin (), end (), result);returnResult } size_type max_size ()Const{returnSize_type (-1); } reference Front () {return*begin (); } const_reference Front ()Const{return*begin (); } reference back () {return* (--end ()); } Const_reference Back ()Const{return* (--end ()); }voidSwap list<t, alloc>& x) {__std::swap (node, x.node);} Iterator insert (iterator position,Constt& x) {Link_type tmp = Create_node (x);    Tmp->next = Position.node;    Tmp->prev = position.node->prev;    (Link_type (position.node->prev))->next = tmp; Position.node->prev = tmp;returntmp }voidPush_front (Constt& x) {insert (Begin (), x);}voidPush_back (Constt& x) {Insert (end (), x);}    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);returnIterator (Next_node); }voidPop_front () {Erase (Begin ());}voidPop_back () {Iterator TMP = end ();  Erase (--TMP); }  };Template<classTclassAlloc>void  list<t, alloc>:: Merge ( list<t, alloc>& x) {//merge sort, merge operationIterator First1 = begin ();  Iterator Last1 = end ();  Iterator First2 = X.begin (); Iterator last2 = X.end (); while(First1! = Last1 && First2! = last2)if(*first2 < *first1)      {iterator next = First2;      Transfer (First1, First2, ++next);    First2 = Next; }Else++first1;if(First2! = last2) Transfer (Last1, First2, last2);}//1) Creates a series of buckets (total).//2) Removes the first element of the list to sort and merges it with the first (i=0th) bucket.//3) If, before the merge, the ith bucket is not empty, the merge the ith buckets with the i+1th bucket.//4) Repeat Step 3 until we merge with an empty bucket.//5) Repeat Step 2 and 3 until the list to sort is empty.//6) Merge all the remaining non-empty buckets together starting from smallest to largest.Template<classTclassAlloc>void  list<t, alloc>:: Sort () {if(Node->next = = Node | | link_type (node->next)->next = = node)return; list<t, alloc>Carry list<t, alloc>counter[ -];intFill =0; while(!empty ()) {Carry.splice (Carry.begin (), * This, begin ());//Remove the element at begin from list, insert into carry    inti =0; while(I < fill &&!counter[i].empty ())      {Counter[i].merge (carry);    Carry.swap (counter[i++]); } carry.swap (Counter[i]);if(i = = fill) ++fill; } for(inti =1; I < fill; ++i) Counter[i].merge (counter[i-1]); Swap (counter[fill-1]);}Template<classTclassAlloc>Template<classPredicate>void  list<t, alloc>:: remove_if (predicate pred) {iterator first = begin (); Iterator last = end (); while(First! = last)    {iterator next = first; ++next;if(Pred (*first)) erase (first);  First = next; }}

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

STL Source Analysis (4): Container (list)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.