STL之slist(一)

         STL list是双向串行。SGI STL另提供了一个单向串行,名为slist。这个容器并不在标准规格之内。

       slist和list的主要差别在于,前者的迭代器属于单向的Forward Iterator,后者的迭代器属于双向的Bidirectional Iterator。此为,slist的功能自然也就受到许多限制。不过,单向串行所耗用的空间更小,某些动作更快,不失为另一种选择。

       slist和list的共同具有一个相同特色是,他们的安插insert,移除erase,接合splice等动作并不会造成原有的迭代器失效。(当然,指向被移除原始的那个迭代器,在移除动作发生之后肯定是会失效)。

       根据STL的习惯,安插动作会将新元素安插于指定位置之前,而非之后。然而做为一个单向串行,slist没有任何方便的办法可以回头定前一个位置,因此它必须从头找起。换句话说,除了slist起始处附近的区域之外,在其它位置上采用insert或erase操作函数,都是不智之举。这便是slist相对于list之下的缺点。为此,slist特别提供了insert_after()和erase_after()提供弹性运用。

       基于同样的效率考虑,slist不提供push_back(),只提供push_front()。因此slist的元素次序会和元素安插位置的次序相反。

       slist的节点

      

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

// 这个是真正的链表结点
template <class T>
struct __slist_node : public __slist_node_base
{
  T data;
};
//全局函数:已知某一节点,插入新节点于其后
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;
}

// 计算链表长度, 时间复杂度O(n)
inline size_t __slist_size(__slist_node_base* node)
{
  size_t result = 0;
  for ( ; node != 0; node = node->next)
    ++result;
  return result;
}
        slist的迭代器
//单链表的迭代器基本结构
struct __slist_iterator_base
{
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  typedef forward_iterator_tag iterator_category; //单向的

  __slist_node_base* node; //指向节点基本结构

  __slist_iterator_base(__slist_node_base* x) : node(x) {}
  void incr() { node = node->next; }

  bool operator==(const __slist_iterator_base& x) const
  {
    return node == x.node;
  }
  bool operator!=(const __slist_iterator_base& x) const
  {
    return node != x.node;
  }
};
// 链表迭代器, 关于迭代器参考<stl_iterator.h>
// 由于是单向链表, 所以不能提供operator --(效率太低)
// 同样也不能提供随机访问能力
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;

  __slist_iterator(list_node* x) : __slist_iterator_base(x) {}
  __slist_iterator() : __slist_iterator_base(0) {}
  __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}

  reference operator*() const { return ((list_node*) node)->data; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
  // 如果编译器支持'->'则重载, 详细见我在<stl_list.h>中的剖析
  pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */

  self& operator++()
  {
    incr();
    return *this;
  }
  self operator++(int)
  {
    self tmp = *this;
    incr();
    return tmp;
  }
};



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值