zoukankan      html  css  js  c++  java
  • 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一样的,这里就不列了。

  • 相关阅读:
    [强网杯青少年专项赛] 惨惨战队WriteUp
    [BUUOJ记录] [HCTF 2018]WarmUp
    [WUST-CTF]Web WriteUp
    PHP check 的一些绕过技术
    [易霖博YCTF]Web WriteUp
    Java backup
    Common Knowledge
    一篇帖子教会你如何获取网盘数据
    python爬虫如何爬知乎的话题?
    浏览器的复制到剪切板功能,兼容所有浏览器,悬浮层不能复制问题解决
  • 原文地址:https://www.cnblogs.com/daocaorenblog/p/5302188.html
Copyright © 2011-2022 走看看