STL Source Notes (16)-Single linked list slist

Source: Internet
Author: User

Overview of STL single-linked list slist introduction

Slist (single linked list) as the name implies, is a one-way list, this container is not within the standard specifications, in my years of code learning career is also the first to hear, since Hou Teacher's book mentioned, it is still learning a clam.

The main difference between the slist and list is that the former iterator belongs to the one-way forward Iterator (read/write), and the latter's iterator belongs to the bidirectional bidirectional Iterator (which can be read and written in both directions). It looks like the slist function should be inferior to list, but because of its one-way list implementation, it consumes less space and some operations are faster.

Recalling the process of inserting elements into a single-linked list in a data structure, the underlying implementation of Slist is a single-linked list, and therefore encounters the trouble we have encountered: when inserting in a location, you must use a pointer to find the previous position in the position to be inserted. This is one of the big drawbacks in Slist, so the book mentions that using an insert or erase algorithm in a non-starting position is unwise.

Slist Source Code Implementation

In the SGI STL source code, the implementation of stl_slist.h Slist is located in

Node design

The core of the container is its underlying storage in the iterator design, for the node design, the use of the inheritance of the relationship, in fact, Simple is a single linked list of nodes: refers to the next node pointer and data


The code is implemented as follows:

//stl_slist.h//单向链表的节点结构struct _Slist_node_base{  _Slist_node_base* _M_next;};//使用继承来实现单链表的节点结构:指针+数据 template <class _Tp>structpublic _Slist_node_base{  _Tp _M_data;};

Based on the characteristics of the single-linked list and the structure of the node, the source code provides a number of internal global functions, these functions are not open to the public, only in some external use of the implementation of the interface directly called, for example:

//全局函数:单链表节点数,其实就是简单的遍历计数inline size_t __slist_size(_Slist_node_base* __node){  0;  for0; __node = __node->_M_next)    ++__result;  return __result;}//全局函数:已知某一节点,插入新节点于其后//返回插入节点之后的指针。inline _Slist_node_base*__slist_make_link(_Slist_node_base* __prev_node,                  _Slist_node_base* __new_node){  __new_node->_M_next = __prev_node->_M_next;  __prev_node->_M_next = __new_node;  return __new_node;}
Iterator design

As shown, iterators are also used in an inherited manner:

//One-way list iterator basic structurestruct_slist_iterator_base{typedefsize_t Size_type;typedefptrdiff_t Difference_type;typedefForward_iterator_tag iterator_category;//Unidirectional read-write iterators_slist_node_base* _m_node;//data type, where the parent class contains only the pointer structure  //Constructor: The parent class contains only constructors with parameters_slist_iterator_base (_slist_node_base* __x): _m_node (__x) {}void_M_INCR () {_m_node = _m_node->_m_next;}//The pointer moves backwards one  BOOL operator==(Const_slist_iterator_base& __x)Const{return_m_node = = __x._m_node;//Overload = = Pointer is equal}BOOL operator!=(Const_slist_iterator_base& __x)Const{return_m_node! = __x._m_node;//overload! = pointer is equal}};//inheritance Relationship//One-way list iterator structureTemplate<class_TP,class_ref,class_ptr>struct_slist_iterator: Public_slist_iterator_base{typedef_SLIST_ITERATOR&LT;_TP, _tp&amp, _tp*> iterator;//define iterator type  typedef_SLIST_ITERATOR&LT;_TP,Const_tp&,Const_tp*> const_iterator;typedef_SLIST_ITERATOR&LT;_TP, _ref, _ptr> _self;typedef_TP Value_type;typedef_ptr pointer;typedef_ref reference;typedef_slist_node<_tp> _node;//Node type  //Constructors  //This is because the parent class contains only constructors with parameters, so subclasses can only display constructors that initialize the parent class_slist_iterator (_node* __x): _slist_iterator_base (__x) {} _slist_iterator (): _slist_iterator_base (0) {}//Copy constructor_slist_iterator (Constiterator& __x): _slist_iterator_base (__x._m_node) {}//* accessor overloads, returning a reference to an elementReferenceoperator*()Const{return((_node*) _m_node)->_m_data; }#ifndef __sgi_stl_no_arrow_operator//-> accessor overloads, returns a reference to the address of the elementPointeroperator()Const{return& (operator*()); }#endif/* __sgi_stl_no_arrow_operator * ///Front + + reload_self&operator+ + () {_m_incr ();//Call the parent function pointer backward to move one    return* This; }//rear-mounted + + reload_selfoperator++(int) {_self __tmp = * This; _M_INCR ();//Call the parent function pointer backward to move one    return__tmp; }//There is no--overload because the forward iterator feature does not support bidirectional operation};
Data structure of Slist

With the foundation of iterator Design and node design, the implementation of single-link list is very simple. Although the algorithm implementation is very simple, but because of the use of inheritance, the design seems to be somewhat complex:

//stl_slist.h//Parent class defines a space constructor, etc.Template<class_TP,class_alloc>struct_slist_base {typedef_alloc Allocator_type; Allocator_type Get_allocator ()Const{returnAllocator_type (); }//constructors, initializing pointers_slist_base (Constallocator_type&) {_m_head._m_next =0; } ~_slist_base () {_m_erase_after (&_m_head,0); }protected:typedefSimple_alloc<_slist_node<_tp&gt, _alloc> _alloc_type;//Space builder type_slist_node<_tp>* _m_get_node () {return_alloc_type::allocate (1); }//Assign a node  void_m_put_node (_slist_node<_tp>* __p) {_alloc_type::d eallocate (__p,1); }//Release a node space  //Delete the element at the next position of the specified element_slist_node_base* _m_erase_after (_slist_node_base* __pos) {_slist_node<_tp>* __next = (_Slist_node<_Tp>*    ) (__pos->_m_next);    _slist_node_base* __next_next = __next->_m_next;    __pos->_m_next = __next_next; Destroy (&__next->_m_data);//Release node_m_put_node (__next);//Free space    return__next_next; }//Delete all elements within the range_slist_node_base* _m_erase_after (_slist_node_base*, _slist_node_base*);protected: _slist_node_base _m_head;//"head pointer", but in fact not a pointer};#endif/* __stl_use_std_allocators * ///According to the code, the deletion should be front-closed and openTemplate<class_TP,class_alloc> _slist_node_base*_slist_base<_tp,_alloc>::_m_erase_after (_slist_node_base* __before_first, _slist_node_base* __last_node) {_slist_node<_tp>* __cur = (_slist_node<_tp>*) (__be Fore_first->_m_next);//The previous position of the recording interval   while(__cur! = __last_node)    {_slist_node<_tp>* __tmp = __cur;    __cur = (_slist_node<_tp>*) __cur->_m_next;    Destroy (&__tmp->_m_data);  _m_put_node (__TMP); } __before_first->_m_next = __last_node;return__last_node;}
//stl_slist.hTemplate<class_TP,class_alloc = __stl_default_allocator (_TP) >classSlist:Private_slist_base<_tp,_alloc>{Private:typedef_slist_base<_tp,_alloc> _base;//Parent class type definition//...//Create a specific element value construction node (intrinsic function)_node* _m_create_node (Constvalue_type& __x) {_node* __node = This->_m_get_node (); __stl_try {construct (&__node->_m_data, __x);//Direct Construction__node->_m_next =0; } __stl_unwind ( This->_m_put_node (__node));return__node;//Return pointer}//Create a node with an element value of 0 (intrinsic function)_node* _m_create_node () {_node* __node = This->_m_get_node ();      __stl_try {construct (&__node->_m_data); __node->_m_next =0; } __stl_unwind ( This->_m_put_node (__node));return__node; }ExplicitSlistConstallocator_type& __a = Allocator_type ()): _base (__a) {}//constructor, specifying the Space configurator typeIn addition, there are many constructors that use their intrinsic functions, such as _m_insert_after_range, which are not listed here. };

In addition to the above simple introduction of the construction and destruction operations, slist as a container, it should have some container unified interface implementation, according to the STL habit, the insert operation will insert the new element in front of the specified position, rather than after, as a single linked list, Slist there is no convenient way to get back to the previous position (without the Prev pointer), based on efficiency considerations, Slist does not provide push_back () to provide only push_front () functions, so that the insertion order and element order will be reversed.

//stl_slist.h//End iterator with head nodeIterator begin () {returnIterator ((_node*) This->_m_head._m_next); } Const_iterator Begin ()Const{returnConst_iterator ((_node*) This->_m_head._m_next);} Iterator End () {returnIterator0); } Const_iterator End ()Const{returnConst_iterator (0); }//Call internal function to find sizeSize_type size ()Const{return__slist_size ( This->_m_head._m_next); }//Determine if it is empty  BOOLEmpty ()Const{return  This->_m_head._m_next = =0; }//Insert element in head  voidPush_front (Constvalue_type& __x) {__slist_make_link (& This->_m_head, _m_create_node (__x)); }//delete element in head  voidPop_front () {_node* __node = (_node*) This->_m_head._m_next; This->_m_head._m_next = __node->_m_next; Destroy (&__node->_m_data); This->_m_put_node (__node); }

STL Source Notes (16)-Single linked list slist

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.