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一样的,这里就不列了。