前言
不同于list
是Forward Iterator
类型的双向链表, slist
是单向链表, 也是Bidirectional Iterator
类型. slist主要耗费的空间小, 操作一些特定的操作更加的快, 同样类似与slist
, 在执行插入和删除操作迭代器都不会像vector使迭代器失效. slist
主要的问题在于它是单向的, 正向迭代器, 只有push_front
, 没有push_back的操作, 指定位置之后的插入和删除时间都是O(1), 而在指定位置之前插入就需要重新遍历链表时间就是O(n), 效率很低.
slist源码
slist
的构成与list
还是异曲同工.
节点结构
将节点的每一部分都进行剥离, 节点是一个结构构成, 数据是继承节点.
struct __slist_node_base
{
__slist_node_base* next; // 只有指向下一个节点的指针
};
// 继承节点指针, __slist_node增加数据
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;
}
寻找指定节点的prev节点. 因为slist是正向迭代器就只有遍历链表
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 const __slist_node_base* __slist_previous(const __slist_node_base* head,const __slist_node_base* node)
{
// 遍历整个链表来寻找
while (head && head->next != node)
head = head->next;
return head;
}
将指定范围的链表剪切到pos链表后
inline void __slist_splice_after(__slist_node_base* pos,__slist_node_base* before_first, __slist_node_base* before_last)
{
if (pos != before_first && pos != before_last) {
__slist_node_base* first = before_first->next;
__slist_node_base* after = pos->next;
// 将before_first之后的调整为before_last后面的链表
before_first->next = before_last->next;
// 将[before_first->next, before_last]插入到pos之后
pos->next = first;
before_last->next = after;
}
}
将链表进行倒转
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;
}
迭代器
之前说过slist
的迭代器是正向的, 现在就来具体分析.
__slist_iterator_base
单向链表的迭代器基本结构
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) {
}
// incr: 只正向.
void incr() {
node = node->next; }