slist

STL list是个双向链表,迭代器是Bidirectional Iterator,而slist 是个单向链表,所以它的迭代器是Forward Iterator.

   两者区别:slist的作为单向的,功能会受到限制,但耗用的空间会更小。所以对它进行插入和删除都不合适,所以slist有其特有的一些功能:insert_after(),erase_after(),它只提供push_front()(slist元素插入的次序会和原来的次序相反),不提供push_back().

   两者共同点:他们的插入、移除,接合等操作不会造成原有的迭代器失效。

   slist的源码架构上运用了继承,如下是数据结构:节点继承关系:

// 这个是链表结点的指针域  
struct __slist_node_base  
{  
  __slist_node_base* next;  
};  

// 这个是真正的链表结点  
template <class T>  
struct __slist_node : public __slist_node_base  
{  
  T data;  
};  

迭代器也是这样的:

struct __slist_iterator_base  
{  
  typedef size_t size_type;  
  typedef ptrdiff_t difference_type;  
  typedef forward_iterator_tag iterator_category; //单向的  
  __slist_node_base* node; //指向节点基本结构    
};  
template <class T, class Ref, class Ptr>  
struct __slist_iterator : public __slist_iterator_base  
{  
  typedef __slist_iterator<T, T&, T*>             iterator;  
  typedef __slist_iterator<T, const T&, const T*> const_iterator;  
  typedef __slist_iterator<T, Ref, Ptr>           self;  
  
  typedef T value_type;  
  typedef Ptr pointer;  
  typedef Ref reference;  
  typedef __slist_node<T> list_node;    
};  

构造和析构节点

private:  
  typedef __slist_node<T> list_node;  
  typedef __slist_node_base list_node_base;  
  typedef __slist_iterator_base iterator_base;  
  
  // 这个提供STL标准的allocator接口  
  typedef simple_alloc<list_node, Alloc> list_node_allocator;  
  
  // 创建一个值为x的结点, 其没有后继结点  
  static list_node* create_node(const value_type& x)  
  {  
    list_node* node = list_node_allocator::allocate();  
    __STL_TRY {  
      construct(&node->data, x);  
      node->next = 0;  
    }  
    __STL_UNWIND(list_node_allocator::deallocate(node));  
    return node;  
  }  
  
  // 析构一个结点的数据, 不释放内存  
  static void destroy_node(list_node* node)  
  {  
    destroy(&node->data);  
    list_node_allocator::deallocate(node);  
  }  

元素操作:

front(),push_front(),pop_front()

const_reference front() const 
{ return ((list_node*) head.next)->data; }  
  
    //从头部取走元素  
  void pop_front()  
  {  
    list_node* node = (list_node*) head.next;  
    head.next = node->next;  
    destroy_node(node);  
  }
 //在头部插入元素  
  void push_front(const value_type& x)  
  {  
    __slist_make_link(&head, create_node(x));  
  }  
  
//全局函数:已知某一节点,插入新节点于其后  
inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,  
                                            __slist_node_base* new_node)  
{  
  new_node->next = prev_node->next;  
  prev_node->next = new_node;  
  return new_node;  
}   

insert_after(),erase_after(),previous()(找到指定节点的前段)

template <class InIter>  
  void insert_after(iterator pos, InIter first, InIter last) {  
    _insert_after_range(pos.node, first, last);  
  } 

  template <class InIter>  
  void _insert_after_range(list_node_base* pos, InIter first, InIter last)  
  {  
    while (first != last) {  
      pos = __slist_make_link(pos, create_node(*first));  
      ++first;  
    }  
  } 

iterator erase_after(iterator pos)  
  {  
    return iterator((list_node*)erase_after(pos.node));  
  }  

  // 擦除pos后面的结点  
  list_node_base* erase_after(list_node_base* pos)  
  {  
    list_node* next = (list_node*) (pos->next);  
    list_node_base* next_next = next->next;  
    pos->next = next_next;  
    destroy_node(next);  
    return next_next;  
  }  

iterator previous(const_iterator pos)  
  {  
    return iterator((list_node*) __slist_previous(&head, pos.node));  
  }  
// 获取指定结点的前一个结点  
inline __slist_node_base* __slist_previous(__slist_node_base* head,  
                                           const __slist_node_base* node)  
{  
  while (head && head->next != node)  
    head = head->next;  
  return head;  
}  

// 链表转置  
inline __slist_node_base* __slist_reverse(__slist_node_base* node)  
{  
  __slist_node_base* result = node;  
  node = node->next;  
  result->next = 0;  
  while(node) {  
    __slist_node_base* next = node->next;  
    node->next = result;  
    result = node;  
    node = next;  
  }  
  return result;  
}  

还有一些元素操作:sort(),merge(),unique()等与list一样的,这里就不列了。

posted on 2016-03-21 15:35  RenewDo  阅读(936)  评论(0编辑  收藏  举报

导航