chapter4 序列式容器:slist


1 概述

STL list是个双向链表。SGI STL另提供了一个单向链表(single linked list),名为slist。

它和list的主要区别在与slist的迭代器属于单向的Forward Iterator,后者的迭代器属于双向的Bidirectional Iterator。

它和list的共同具有的一个特点:它们的插入、移除、接合等操作不会造成原有迭代器的失效。

根据STL的习惯,插入操作一般会将新元素插入指定位置之前,而非之后。然而对于单向链表,它无法方便地回头定出前一个位置,因此必须从头找起。所以除了slist起点处附近的区域外,在其他位置上采用insert或erase操作,都属于不智之举。为此,slist提供insert_after()和erase_after()供灵活运用。

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

2 slist的节点和迭代器

在这里插入图片描述
节点结构:

struct __slist_node_base {
    __slist_node_base* next;
};
template<class T>
struct __slist_node : public __slist_node_base {
    T data;
}

迭代器结构:

//...
template<class T, class Ref, class Ptr>
struct __slist_iterator : publi __slist_iterator_base {
    //...
    typedef __slist_node<T> list_node;
    
    reference operator*() const { return ((list_node*)node)->data; }
    pointer operator->() const { return &(operator*()); }
    
    self& operator++() {
        incr(); //前进一个节点
        return *this;
    }
    self operator++(int) {
        self tmp = *this;
        incr();
        return tmp;
    }
    
    //没有实现operator--,因为是一个forward iterator
}

3 slist的数据结构

template <class T, class Alloc = alloc>
class slist {
//...
private:
    //...
    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 destory_node(list_node* node) {
        destory(&node->data);	//析构元素
        list_node_allocator::deallocator(node);	//释放空间
    }  
    
    //...
public:
    iterator begin() { return iterator((list_node*)head.next); }
    iterator end() {return iterator(0); }
};

4 slist的元素操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值