IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> C++初阶----list模拟实现 +(迭代器总结) -> 正文阅读

[系统运维]C++初阶----list模拟实现 +(迭代器总结)

1)list介绍

结构,list的迭代器用类封装为了实现重载,<T,T&,T>*

template < class T, class Alloc = allocator<T> > class list;

①:list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代
②: list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素
③: list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效
④: 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好
⑤:与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)


2)list使用

详细请参考:cplusplus -list

①list构造函数

②list的访问及遍历

③list容量操作

③list修改

注意容器尽量只用自己的swap,库中的实现如下

template <class T> void swap ( T& a, T& b )
{
 T c(a); a=b; b=c;
}

对于list容器的swap,只用交换头指针就行了,
库中的T c(a);语句是进行的深拷贝,自然不推荐使用

④list操作

①:list的成员函数sort不建议使用,因为是归并排序,效率低无意义(链表的快排有缺陷有序时候是O(N^2))
②: 注意list不能使用库函数的sort,库函数是使用的快排

  1. list迭代器不是原生指针,++不是取到下一个数据,地址是随机的,要实现找到下一个位置的这个操作本身实现就需要O(N)的时间复杂度,所以无意义
  2. 库函数里的sort用了迭代器相减,变相只支持原生指针,list迭代器不能相减

3)list模拟实现(结构:三个类)

list底层是一个带头双向循环链表

Ⅰ.节点类

前面说过struct中的成员默认都是公有的(public)

//1. List的节点类
template<class T>
struct ListNode
{
   ListNode(const T& val = T())//匿名对象缺省值
       :_prev(nullptr)
       ,_next(nullptr)
       ,_val(val)
   {}
   ListNode<T>* _prev;
   ListNode<T>* _next;
   T _val;
};

Ⅱ. List的迭代器类

  1. 当我们要使用const_iterator时,只能重新定义一个const版的List的迭代器类
  2. 而const_iterator和iterator只有解引用的重载不一样我们使用这种方法
  3. 类模板参数改为三个分别对应T,T&,T*
template<class T, class Ref, class Ptr>
struct ListIterator
{
   typedef ListNode<T> Node;
   typedef ListIterator<T, Ref, Ptr> Self;
   Node* _pNode  
};

1.构造

默认构造和拷贝构造

注意 在List的迭代器类里不需要自定义析构函数,默认析构函数已经够用了

ListIterator(Node* pNode = nullptr)
   :_pNode(pNode)
{}
ListIterator(const Self& l)
	: _pNode(l._pNode)
{}

2.运算符重载

①解引用*和->重载

这里是引用

Ref operator*()
{
    return _pNode->_val;
}
//Self* operator->();
②前置/后置++/ - -

注意 后置,临时变量出作用域销毁,不能引用返回

Self& operator++()//注意 这是前置++
{
   _pNode = _pNode->_next;
   return *this;
}
Self operator++(int)//注意 后置++要加int
//注意 临时变量出作用域销毁,不能引用返回
{
   Self tmp = _pNode;
   _pNode = _pNode->_next;
   return tmp;
}
Self& operator--()//注意 这是前置++
{
   _pNode = _pNode->_prev;
   return *this;
}
Self operator--(int)//注意 后置++要加int
{
   Self tmp = _pNode;
   _pNode = _pNode->_prev;
   return tmp;
}
③关系运算符!= ==重载
bool operator!=(const Self& it) const
{
    return _pNode != it._pNode;
}
bool operator==(const Self& it) const
{
    return (_pNode == it._pNode);
}

Ⅲ. list类

1.构造

2.赋值运算符重载

3. 容量

4.修改操作

insert
// 在pos位置前插入值为val的节点
iterator insert(iterator pos, const T& val)
{
   Node* cur = pos._pNode;
   Node* prev = cur->_prev;
   Node* newnode = new Node(val);
   newnode->_next = cur;
   cur->_prev = newnode;
   prev->_next = newnode;
   newnode->_prev = prev;
   //1. 原始 
   //iterator ret(newnode);//
   //return ret;//
   
   //2. 隐式类型转换
   //return newnode;

   //3. 匿名对象
   return iterator(newnode);//== return ListIterator<T>(newnode); 

返回值有三种写法

  1. 原始
    iterator ret(newnode);
    return ret;
  2. 隐式类型转换
    return newnode;
  3. 匿名对象
    return iterator(newnode);
erase
// 删除pos位置的节点,返回该节点的下一个位置
iterator erase(iterator pos)
{
   assert(pos!=end());
   Node* cur = pos._pNode;
   Node* prev = cur->_prev;
   prev->_next = cur->_next;
   cur->_next->_prev = prev;
   delete cur;
   return iterator(prev->_next);
}

5.非成员函数重载

swap

4)迭代器总结

①:迭代器从使用功能分类

  1. 正向/正向const
  2. 反向/反向const

②:迭代器从底层结构分类

  1. 单向
    单链表/哈希表(只支持++)
  2. 双向
    双向链表/二叉树/map(支持++/ - -)
  3. 随机
    dequeue/vector/string/map(支持++ /- -/ +/ -)

随机>双向>单向(包含关系)
在这里插入图片描述
迭代器在不暴露容器底层实现细节的情况下,提供统一的方式去修改容器中储存的数据,是算法和容器的胶合剂

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-12 19:59:45  更:2021-11-12 20:02:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:22:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码