1. slist概述
slist,即我们数据结构课程中所学的单链表,与之非常类似的是我们前面所解析到的list
- slist与list的主要差别在于:slist的迭代器属于单向的Forward iterator,list的迭代器则属于Bidirectional iterator;因此slist的功能受到限制,不过其耗用空间比较少,某些操作快
- 作为一个单向链表,其局限性在于插入的时候需要将元素插入到指定位置之前,然后没有办法回头定出前一个位置,因此除了在slist头尾及附近的位置之外,在其它位置上不采用insert或erase操作
2. slist的节点及迭代器
- slist节点及迭代器在设计上比list更为复杂,使用了继承关系,即节点继承自__slist_node_base,迭代器继承自__slist_iterator_base,这种设计方式被称为
双层设计
,在后续的RB-tree设计中也能再次看到
2.1节点设计:
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* next_node)
{
new_node->next = prev_node->next;
prev_node->next = new_node;
return new_node;
}
inline size_t __slist_size(__slist_node_base* node)
{
size_t result = 0;
for (; node != 0; node = node->next)
++result;
return result;
}
2.2 迭代器设计:
struct __slist_iterator_base {
__slist_node_base* node;
__slist_iterator_base (__slist_node_base* x) : node(x) {}
void incr() { node = node->next; }
bool operator== (const __slist_node_base& x) const {
return node == x.node;
}
bool operator!=(const __slist_node_base& x) const {
return node != x.node;
}
};
struct __slist_iterator : public __slist_iterator_base {
reference oeprator*() const { return ((list_node*) node) -> data; }
reference operator->() const { return &(oeprator*()); }
self& operator++()
{
incr();
return *this;
}
self operator++(int)
{
self tmp = *this;
incr();
return tmp;
}
};
3. 数据结构
- slist的基本实现,创建节点、释放节点以及对元素的一些基本操作,部分源码如下:
template <class T, class Alloc = alloc>
class slist {
public:
private:
static list_ndoe* create_node(const value_type& x) {
list_node* node = list_node_allocator::allocate();
__STL_TRY {
construcr(&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);
}
private:
list_node_base head;
public:
slist() { head.next = 0;}
~slist() { clear();}
void swap (slist& l) {
list_node_base* tmp = head.next;
head.next = l.head.next;
l.head.next = tmp;
}
};
4. 元素操作
操作 |
功能 |
front |
取头部元素 |
push_front |
从头部插入元素 |
pop_front |
从头部取走元素 |
#include <iostream>
#include <slist>
using namespace std;
int main(int argc, char** argv) {
slist<int> sli;
cout << " size = " << sli.size() << endl;
sli.push_front(9);
sli.push_front(1);
sli.push_front(2);
sli.push_front(3);
sli.push_front(4);
cout << " size = " << sli.size() << endl;
slist<int>::iterator it1 = sli.begin();
slist<int>::iterator it2 = sli.end();
for (; it1 != it2 ; ++it1)
cout << *it1 << ' ';
cout << endl;
cout << sli.front();
return 0;
}