STL source code profiling-list

Source: Internet
Author: User

Compared with the continuous linear space of vector, list is much more complicated. Its advantage is that each time an element is inserted or deleted, it is configured or released. Therefore, the use of list for space is absolutely accurate and will not be wasted at all. In addition, for element insertion or removal at any position, list is always a constant time.
List is not only a two-way linked list, but also a ring two-way linked list. In addition, there is an important property that neither the insert operation nor the join operation will invalidate the original list iterator, which is not true in the vector. Because the insert operation of vector may cause memory reconfiguration, all the original iterators become invalid. Even the list element deletion operation (erase) is invalid only the iterator that points to the deleted element. Other iterators are not affected.
The following is the list node, iterator data structure design, and list source code analysis:

//////////////////////////////////////// //////////////////////////////////////// // List node, provide two-way access //////////////////////////////////// //////////////////////////////////////// /// // -------- // | next | ----------> | next | // -------- // | Prev | <---------- | Prev | //------- --------- // | Data | //--------------------------------//////////////// //////////////////////////////////////// //// // template <class T> struct _ list_node {typedef void * void_pointer; void_pointer next; void_pointer Prev; t data ;}; // as to why the default parameter is not used, this is because some compilers cannot provide derivation capabilities, // The author does not want to maintain two pieces of code, so the default parameter template <class T, class ref, class PTR> struct is not used. _ List_iterator {typedef _ list_iterator <T, T &, T *> iterator; // the STL standard enforces typedef _ list_iterator <t, ref, PTR> self; typedef partition; 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; // The iterator must contain a common pointer pointing to the list node _ list_iterator (link_type X): n Ode (x) {}__ list_iterator (const iterator & X): node (X. node) {}// in STL algorithm, the iterator must provide support for bool operator ==( const self & X) const {return node = x. node;} bool Operator! = (Const self & X) const {return node! = X. node;} // The following pair of iterator values (dereference) take the data value of the node reference operator * () const {return (* node ). data ;}// The following is the standard practice of the iterator member access sub-operator pointer operator-> () const {return & (operator *());} // The prefix is automatically added and 1 is added to the iterator, that is, the forward node self & operator ++ () {node = (link_type) (* node ). next); return * This;} // suffix auto-increment. You need to generate a copy of your own, and then operate on yourself. Finally, the copy self operator ++ (INT) is returned) {self TMP = * This; ++ * This; return TMP;} // The prefix auto-minus self & operator -- () {node = (link_typ E) (* node ). PREV); return * This;} self operator -- (INT) {self TMP = * This; -- * This; return TMP ;}}; //////////////////////////////////////// //////////////////////////////////////// // list is not only a two-way linked list, and it is also a ring two-way linked list ////////////////////////////////// //////////////////////////////////////// /// // end () header node begin () // begin vertex failed // -------- // ----> | next | ----------> | next | ----------> | Next | ------ // | -------- | // | -- | Prev | <---------- | Prev | <-- | // | -------- | // | data | // | -------- | // | // | -------- | // --- |-| next | <---------- | next | <------ ---- | Next | <-- | -- // | -------- | //> | Prev | ----------> | Prev | ----/ /-------- // | data | //--------------------------------/////////////// //////////////////////////////////////// /// // allocator is alloc by default, for the specific version, see <stl_alloc.h> template <class T, class al Loc = alloc> class list {protected: typedef void * void_pointer; typedef _ list_node <t> list_node; // exclusive space configurator, each time a node is configured with typedef simple_alloc <list_node, alloc> Primary; public: typedef t value_type; typedef value_type * pointer; typedef value_type & reference; typedef list_node * link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _ list_iterator <T, T &, T *> iterator; protecte D: link_type node; // as long as a pointer, it indicates that the entire ring two-way linked list // allocates a new node. Note that the structure is not performed here. // construct the construct that is handed over to the global construct, see <stl_stl_uninitialized.h> link_type get_node () {return list_node_allocator) {list_node_allocator: deallocate (p) ;}// generate (configure and construct) a node. First allocate the memory and then construct the node. // note: commit or rollbacklink_type create_node (const T & X) {link_type P = get_node (); construct (& P -> Data, x); Return P;} // analysis node element, and release the memory void destroy_node (link_type p) {destroy (& P-> data ); put_node (p);} protected: // void empty_initialize () {node = get_node (); // configure a Node space, point node to its node-> next = node; // point the node header and tail to itself, with no element value node-> Prev = node ;} // create a linked list with a value of N nodes // Note: commit or rollbackvoid fill_initialize (size_type N, const T & Value) {empty_initialize (); __stl_try {// here insert operation time complexity O (1) insert (begin (), N, value) ;:__ stl_unwind (clear (); put_node (node);} public: List () {empty_initialize ();} iterator begin () {return (link_type) (* node ). next);} // The linked list forms a ring. when it refers to the header node, that is, enditerator end () {return node ;} // The header node points to itself, indicating that there is no element in the linked list bool empty () const {return node-> next = node;} // use the global function distance () for calculation, time complexity O (n) size_type size () const {size_type result = 0; distance (begin (), end (), result); return result;} size_type m Ax_size () const {return size_type (-1);} reference Front () {return * begin ();} reference back () {return * (-- end ());} //////////////////////////////////////// //////////////////////////////////////// // Insert the element at the specified position ///////////////////////////////// //////////////////////////////////////// //////// insert (iterator position, const T & X) // returns // create_node (x) // P = get_node (); --------> list_node_allocator: Llocate (); // construct (& P-> data, x); // returns // TMP-> next = position. node; // TMP-> Prev = position. node-> Prev; // (link_type (position. node-> PREV)-> next = TMP; // position. node-> Prev = TMP; //////////////////////////////////////// //////////////////////////////////////// iterator insert (iterator position, const T & X) {link_type TMP = create_node (x); // generate a node // adjust the bidirectional pointer so that TMP can be inserted into TMP-> next = position. node; TMP-> PR Ev = position. node-> Prev; (link_type (position. node-> PREV)-> next = TMP; position. node-> Prev = TMP; return TMP;} // insert n elements whose values are X at the specified position. For detailed parsing, see void insert (iterator POs, size_type N, const T & X); void insert (iterator POs, int N, const T & X) {insert (Pos, (size_type) n, x);} void insert (iterator POs, long N, const T & X) {insert (Pos, (size_type) n, x);} // Insert the void push_front (const T & X) at the front end of the linked list) {insert (B Egin (), x);} // Insert the node void push_back (const T & X) {insert (end (), x) at the end of the linked list );} // remove the 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);} // erase the node of a range. For details about the parsing, see implementation part iterator erase (ITE Rator first, iterator last); void resize (size_type new_size, const T & X); void resize (size_type new_size) {resize (new_size, T ());} void clear (); // Delete the first node of the linked list void pop_front () {erase (begin ();} // Delete the last node of the linked list void pop_back () {iterator TMP = end (); erase (-- TMP);} List (size_type N, const T & Value) {fill_initialize (n, value);} List (int n, const T & Value) {fill_initialize (n, value);} List (long N, const T & Value) {fill_initialize (n, value );}~ List () {// release all nodes // use the global function distance () for calculation. time complexity O (n) size_type size () const {size_type result = 0; distance (begin (), end (), result); return result;} Clear (); // release the header node put_node (node) ;}list <t, alloc> & operator = (const list <t, alloc> & X); protected: //////////////////////////////////////// //////////////////////////////////////// // set [first, last) all elements in the table are moved to the position. // If last = position, the linked list does not change. Row operation ////////////////////////////////////// //////////////////////////////////////// /// initial status // first last // begin failed // -------- // | next | --> | next | --> | next | //... ------------------------... ------------------------... // | Prev | <-- | Prev | //-------------------------------- -------- /// Position // else // -------- // | next | --> | next | --> | next | //... ------------------------------------------------... // | Prev | <-- | Prev | //------------------------------------------------// // status after the operation is complete // first // | // -------------- | ---------------- ---------------------- // | ------------ | Previous | last // | bytes | Bytes/-------- | -------- // | next | -- | -----> | next | --> | next | ----- | --> | next | //... -------- | ----------------... -------- | ----------------... // | Prev | <--- | Prev | <-- | ----- | Prev | <-- | Prev | //- ------- | -------- // | ------ | // ------- | ---------------------------- | // | ----------------------------- // | Position/| condition/-------- | -------- // | next | --> | next | --> | next | //... -------- | -------------- ------------------... // | Prev | <-- | Prev | <--- ------ | Prev | <-- | Prev | //------------------------------------------------/ //////////////////////////////////////// /// // void transfer (iterator position, iterator first, iterator last) {If (position! = Last) // If last = position, the linked list is not changed and no operation is performed {(* (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: // move the linked list X to the position indicated by position before Vo Id splice (iterator position, list & X) {If (! X. empty () Transfer (Position, X. begin (), X. end () ;}// move the content pointed to by I in the linked list to void splice (iterator position, list &, iterator I) {iterator J = I; ++ J; if (position = I | position = J) return; Transfer (Position, I, j);} // set [first, last} The Void splice (iterator position, list &, iterator first, iterator last) {If (first! = Last) Transfer (position, first, last);} void remove (const T & value); void unique (); void merge (List & X); void reverse (); void sort () ;}; // destroy all nodes. Empty 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_node (TMP) ;}// restore the original node state node-> next = node; node-> Prev = node;} // linked list assignment operation // if the current container element is less than the X container, the redundant elements are parsed, // otherwise, insert the call insert into the remaining element template in x <class T, class alloc> List <t, alloc> & list <t, alloc> :: operator = (const list <t, alloc> & X) {If (this! = & X) {iterator first1 = begin (); iterator last1 = end (); const_iterator first2 = x. begin (); const_iterator last2 = x. end (); While (first1! = Last1 & first2! = Last2) * first1 ++ = * first2 ++; If (first2 = last2) Erase (first1, last1); else insert (last1, first2, last2 );} return * This;} // remove all adjacent duplicate nodes in the container // time complexity O (n) // operator required for Custom Data Types = () reload 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 ;}// assume that both the current container and X are in order, ensure that the two containers are still sorted after merging the template <class T, class alloc> void list <t, alloc >:: Merge (list <t, alloc> & X) {iterator first1 = begin (); iterator last1 = end (); iterator first2 = x. begin (); iterator last2 = x. end (); // note: the premise is that both lists have been incrementally sorted 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 );}

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.