欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > STL源码剖析(侯捷版本) —— 第四章 序列式容器(三)

STL源码剖析(侯捷版本) —— 第四章 序列式容器(三)

2024/12/24 12:52:46 来源:https://blog.csdn.net/weixin_42255569/article/details/144670845  浏览:    关键词:STL源码剖析(侯捷版本) —— 第四章 序列式容器(三)

传送门

STL源码剖析(侯捷版本) —— 第一章 STL 概论与版本简介
STL源码剖析(侯捷版本) —— 第二章 空間配置器 allocator
STL源码剖析(侯捷版本) —— 第三章 迭代器(Iterators)与Traits编程技巧在C++ STL中的应用

STL源码剖析(侯捷版本) —— 第四章 序列式容器(一)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(二)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(三)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(四)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(五)

文章目录

  • SGI STL 的 `list`
    • 1. `list` 的节点 (`node`)
      • 双向链表的基本结构
      • 节点的实现
    • 2. `list` 的迭代器
      • 迭代器基类
      • 前移与后移
      • 比较操作
    • 3. `list` 的数据结构
      • `list` 的基类
      • 构造与析构
      • 空间管理
    • 4. 特点总结

SGI STL 的 list

在 SGI STL 中,list 是一个环状双向链表,支持在任意位置进行高效的插入和删除操作。这些操作的时间复杂度为常数时间。


1. list 的节点 (node)

双向链表的基本结构

list 的底层是由一个节点结构组成的双向链表:

struct _List_node_base {_List_node_base* _M_next;_List_node_base* _M_prev;
};

每个节点通过 _M_next_M_prev 指针连接,构成链表。

节点的实现

每个 list 节点存储链表的值:

template <class _Tp>
struct _List_node : public _List_node_base {_Tp _M_data; // 节点存储的值
};

2. list 的迭代器

由于 list 的节点在内存中不连续存储,迭代器需要具备前移后移的能力。因此,list 提供了双向迭代器Bidirectional iterator)。

迭代器基类

struct _List_iterator_base {typedef size_t                     size_type;typedef ptrdiff_t                  difference_type;typedef bidirectional_iterator_tag iterator_category; // 双向迭代器标签_List_node_base* _M_node; // 指向节点的指针
};

前移与后移

void _M_incr() { _M_node = _M_node->_M_next; } // 前移
void _M_decr() { _M_node = _M_node->_M_prev; } // 后移

比较操作

bool operator==(const _List_iterator_base& __x) const {return _M_node == __x._M_node;
}
bool operator!=(const _List_iterator_base& __x) const {return _M_node != __x._M_node;
}

3. list 的数据结构

list 的数据结构是一个环状的双向链表,遵循 STL 的前闭后开原则。

list 的基类

template <class _Tp, class _Alloc>
class _List_base {
public:typedef _Alloc allocator_type;allocator_type get_allocator() const { return allocator_type(); }

构造与析构

构造函数会初始化一个空白节点用于标记链表的尾部:

  _List_base(const allocator_type&) {_M_node = _M_get_node();_M_node->_M_next = _M_node;_M_node->_M_prev = _M_node;}

析构函数会清空链表并释放节点:

 _List_base(const allocator_type&) {_M_node = _M_get_node();_M_node->_M_next = _M_node;_M_node->_M_prev = _M_node;}

空间管理

list 使用专属的空间配置器管理节点内存:

protected:typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type;_List_node<_Tp>* _M_get_node() {return _Alloc_type::allocate(1); // 分配一个节点}void _M_put_node(_List_node<_Tp>* __p) {_Alloc_type::deallocate(__p, 1); // 释放一个节点}
};

4. 特点总结

  • list 的底层是一个环状双向链表
  • 节点使用 _M_next_M_prev 连接,形成环状结构。
  • 默认有一个尾端的空白节点,用于支持 STL 的前闭后开原则。
  • 插入与删除操作时间复杂度为常数时间。
  • 提供双向迭代器支持前移和后移操作。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com