STL list源码解析
1.list的底层实现
template<class T>
struct __list_node
{typedef __list_node<T>* node_pointer;node_pointer prev;node_pointer next;T data;
}
底层是双向链表
2.迭代器的实现
template <class T>
class __list_iterator
{typedef __list_iterator<T> self;typedef __list_node<T>* link_type;link_type ptr;__list_iterator(link_type p = NULL): ptr(p) {}......T& operator *(){return ptr->data;}T* operator->(){return &(operator*());}self& operator++(){ptr = ptr->next;return *this;}self operator++(int){self tmp = *this;++(*this);return *tmp;}self& operator--(){ptr = ptr->prev;return *this;}self operator--(int){self tmp = *this;--(*this);return tmp;}bool operator==(const __list_iterator& rhs){return ptr == rhs.ptr;}bool operator!=(const __list_iterator& rhs){return !(*this==rhs);}
}
3.list的实现
template<class T, Alloc=alloc>
class list
{
protected:typedef __list_node<T> list_node;typedef simple_alloc<Alloc, list_node> list_node_allocator;public:typedef T value_type;typedef T& reference;typedef value_type* pointer;typedef list_node* link_type;typedef const value_type* const_pointer;typedef size_t size_type;public:typedef __list_iterator<value_type> iterator;private:link_type node; // 只要一个指针,便可表示整个环状双向链表
public:iterator begin() {return (link_type)(node->next);} // 构造函数iterator end() {return node;}size_type size() {size_type result = 0;distance(begin(), end(), result);return result;}bool empty() const {return node->next == node;}reference front() {return *begin();}refrence back(); {return *(--end());}
}
下面的操作用来配置,释放,构造,销毁一个节点
申请一个节点的内存
link_type get_node() {return list_node_allocator::allocate();}
释放一个节点
void put_node(link_type p) {list_node_allocator::deallocate(p);}
申请内存并构造一个节点
link_type create_node(const T& x)
{link_type p = get_node();construct(&p->data, x);return p;
}
析构并释放一个节点
void destroy_node(link_type p)
{destroy(&p->data);put_node(p);
}
5.构造函数
public:
list() {empty_initialize();}
protected:void empty_initialize()
{node = get_node();node->next = node;node->prev = node;
}
6.插入
iterator insert(iterator position, const T& x)
{link_type tmp = create_node(x);tmp->next = position.node;tmp->prev = position.node->prev;(link_type(position.node->prev))->next = tmp;position.node->prev = tmp;return tmp;
}
push_front():
void push_front(const T& x) {insert(begin(), x);}
push_back():
void push_back(const T& x) {insert(end(), x);}
erase(iterator position)
void erase(iterator position)
{link_type prev_node = (link_type)(position.node->prev);link_type next_node = (link_type)(position.node->next);prev_node->next = next_node;next_node->prev = prev_node;destroy_node(position.node);return iterator(next_node);
}
移除头节点
void pop_front(){erase(begin());}
移除末尾节点
void pop_back() {erase(--end());}
清空节点
template<class T, Alloc=alloc>
void list<T, Alloc> clear()
{link_type cur = begin();while (cur != node){link_type tmp = cur;cur = cur->next;destroy_node(tmp);}node->prev = node;node->next = node;
}
将值为value的元素都去掉
void remove(const T& x)
{iterator first = begin();iterator last = end();while (first != last){iterator next = first;++next;if (*first == value) erase(first);first = next;}}
双向链表去重
void unique()
{iterator first = begin();iterator last = end();if (first == last) return;iterator next = first;while (++next != last){if (*next == *first) erase(next);else first = next;next = first;}
}
STL list源码解析相关推荐
- libco源码解析(2) 创建协程,co_create
libco源码解析(1) 协程运行与基本结构 libco源码解析(2) 创建协程,co_create libco源码解析(3) 协程执行,co_resume libco源码解析(4) 协程切换,coc ...
- UWA学堂上新|虚幻引擎源码解析——基础容器篇
文章简介 文章主要介绍了虚幻引擎的基础容器的内部数据结构和实现原理,以及在实践中的应用,性能优化等方面.包括:TArray.TSparseArray.TSet.TMap等基础容器,TQueue.TTr ...
- KiCAD源码解析(2):根目录CmakeList解析
KiCAD源码解析(2):根目录CmakeList解析 Kicad根目录CmakeList解析 提示:想学习cmake的看此篇文章也用处多多 根目录CMakeLists.txt解析 KiCAD源码解析 ...
- python整型数据源码分析_Python2 基本数据结构源码解析
Python2 基本数据结构源码解析 Contents 0x00. Preface 0x01. PyObject 0x01. PyIntObject 0x02. PyFloatObject 0x04. ...
- 红黑树分析与JDK8中HashMap源码解析
红黑树分析与JDK8中HashMap源码解析 BST O(1), O(n), O(logn), O(nlogn) 的区别 红黑树-RBTree 插入数据 HashMap中红黑树的插入操作 HashMa ...
- 谷歌BERT预训练源码解析(二):模型构建
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...
- 谷歌BERT预训练源码解析(三):训练过程
目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...
- 谷歌BERT预训练源码解析(一):训练数据生成
目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...
- Gin源码解析和例子——中间件(middleware)
在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...
最新文章
- 在MAC上搭建eclipse+android开发环境以及eclipse的svn插件的安装
- kafka消费者命令行的使用方法
- PowerDesigner中NAME和COMMENT的互相转换,需要执行语句
- 10.2.2 选择器
- 网易校园招聘历年经典面试题汇总:C++研发岗
- 用canvas实现手写签名功能
- RT thread 设备驱动组件之USART设备
- python之类介绍
- In-App Purchase 实战
- 流量变现|谁能拒绝私藏一套app流量变现的攻略呢?
- 网站关键词选择的四大步骤
- java当前日期星期几_java获取当前日期是星期几
- 重学Elasticsearch第3章 : ElasticSearch高级查询、索引库原理、倒排索引、DSL高级检索
- 欧姆龙PLC HostLink通讯 C-MODE格式
- 使用php的GD库拼接图片
- C语言计算今天是一年的第几周
- Automotive SPICE 简介
- Flex工具下载链接
- hualinux 编程概念 3.16:DevOps 详解
- Go语言基础——基础语法