C++初阶(十四)list

在这里插入图片描述


📘北尘_:个人主页

🌎个人专栏:《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》

☀️走在路上,不忘来时的初心

文章目录

  • 一、 list的介绍
  • 二、list的模拟实现
    • 1、list的节点
    • 2、list 的迭代器
    • 3、list
    • 4、打印
    • 5、完整代码


一、 list的介绍

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

在这里插入图片描述


二、list的模拟实现

1、list的节点

template<class T>struct list_node{T _data;list_node<T>* _prev;list_node<T>* _next;list_node(const T& x = T()):_data(x), _next(nullptr), _prev(nullptr){}};

2、list 的迭代器

template<class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> self;Node* _node;__list_iterator(Node* node):_node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator--(){_node = _node->_prev;return *this;}self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};

3、list

template<class T>class list{typedef list_node<T> Node;public:typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}list(list<T>& lt){empty_init();for (auto e : lt){push_back(e);}}list<T>& operator=(list<T> lt){swap(lt);return *this;}void swap(list<T> lt){std::swap(_size, lt._size);std::swap(_head, lt._head);}iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* newnode = new Node(x);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;return iterator(newnode);}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;delete cur;prev->_next = next;next->_prev = prev;--_size;}size_t size(){return _size;}void clear(){iterator it = begin();while (it != end){it = erase(it);}}void push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void push_back(){erase(end());}void pop_back(){erase(begin());}private:Node* _head;size_t _size;};

4、打印

template<typename Container>void print_container(const Container& con){typename Container::const_iterator it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;}void test_list(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);print_container(lt);list<string> lt1;lt1.push_back("1111111111111");lt1.push_back("1111111111111");lt1.push_back("1111111111111");lt1.push_back("1111111111111");lt1.push_back("1111111111111");print_container(lt1);vector<string> v;v.push_back("222222222222222222222");v.push_back("222222222222222222222");v.push_back("222222222222222222222");v.push_back("222222222222222222222");print_container(v);}
}
int main()
{bit::test_list();return 0;
}

5、完整代码

#include<iostream>
#include<string>
#include<vector>
using namespace std;
namespace bit
{template<class T>struct list_node{T _data;list_node<T>* _prev;list_node<T>* _next;list_node(const T& x = T()):_data(x), _next(nullptr), _prev(nullptr){}};template<class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> self;Node* _node;__list_iterator(Node* node):_node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator--(){_node = _node->_prev;return *this;}self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};template<class T>class list{typedef list_node<T> Node;public:typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}list(list<T>& lt){empty_init();for (auto e : lt){push_back(e);}}list<T>& operator=(list<T> lt){swap(lt);return *this;}void swap(list<T> lt){std::swap(_size, lt._size);std::swap(_head, lt._head);}iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* newnode = new Node(x);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;return iterator(newnode);}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;delete cur;prev->_next = next;next->_prev = prev;--_size;}size_t size(){return _size;}void clear(){iterator it = begin();while (it != end){it = erase(it);}}void push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void push_back(){erase(end());}void pop_back(){erase(begin());}private:Node* _head;size_t _size;};template<typename Container>void print_container(const Container& con){typename Container::const_iterator it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;}void test_list(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);print_container(lt);list<string> lt1;lt1.push_back("1111111111111");lt1.push_back("1111111111111");lt1.push_back("1111111111111");lt1.push_back("1111111111111");lt1.push_back("1111111111111");print_container(lt1);vector<string> v;v.push_back("222222222222222222222");v.push_back("222222222222222222222");v.push_back("222222222222222222222");v.push_back("222222222222222222222");print_container(v);}
}
int main()
{bit::test_list();return 0;
}

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/263544.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Doocker还原容器启动命令参数

get_command_4_run_container可以还原docker执行命令, 这是个第三方包&#xff0c;需要先安装&#xff1a; docker pull cucker/get_command_4_run_container 命令格式&#xff1a; docker run --rm -v /var/run/docker.sock:/var/run/docker.sock cucker/get_command_4_run…

Linux中的SNAT与DNAT实践

Linux中的SNAT与DNAT实践 1、SNAT的介绍1.1&#xff0c;SNAT概述1.2&#xff0c;SNAT源地址转换过程1.3&#xff0c;SNAT转换 2、DNAT的介绍2.1&#xff0c;DNAT概述2.2&#xff0c;DNAT转换前提条件2.3&#xff0c;DNAT的转换 3、防火墙规则的备份和还原4、tcpdump抓包工具的运…

ubuntu16.04升级openssl

Ubuntu16.04 默认带的openssl版本为1.0.2 查看&#xff1a;openssl version 1.下载openssl wget https://www.openssl.org/source/openssl-1.1.1.tar.gz 编译安装 tar xvf openssl-1.1.1.tar.gz cd openssl-1.1.1 ./config make sudo make install sudo ldconfig 删除旧版本 su…

【git教程】

目录 git与SVN的区别&#xff1a;集中式与分布式的区别Windows上安装Git创建版本库/仓库&#xff08;repository&#xff09;将文件添加到repository报错处理 查看仓库的状态版本回退工作区和暂存区管理和修改撤销修改删除文件远程仓库添加远程仓库警告解除本地和远程的绑定关系…

【数电笔记】58-同步D触发器

目录 说明&#xff1a; 1. 电路组成 2. 逻辑功能 3. 特性表、特性方程 4. 状态转移图 例题 5. 同步D触发器的特点 6. 集成同步D触发器&#xff1a;74LS375 74LS375内部原理 说明&#xff1a; 笔记配套视频来源&#xff1a;B站本系列笔记并未记录所有章节&#xff0c;…

基于SSM的点餐系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

2024年法定节假日 法定上班日 工作日 休息日一览表

2024年法定节假日 法定上班日 工作日 休息日一览表 第一列&#xff1a;日期&#xff0c; 第二列&#xff1a;星期几&#xff0c; 第三列&#xff1a;枚举值2个&#xff0c;只有休息日或工作日&#xff0c; 第四列&#xff1a;枚举值4个&#xff1a;法定节假日&#xff0c;法…

Mybatis源码解析1:环境搭建

Mybatis源码解析1&#xff1a;环境搭建 1.项目结构2.pom.xml3.table.sql4. mybatis-config5.Blog6.BlogMapper7.BlogMapper.xml8.MyInterceptor9. InterceptorTest 1.项目结构 github老是打不开&#xff0c;直接贴代码吧 2.pom.xml <?xml version"1.0" encod…

GEE影像升尺度(10m->250m)

GEE影像升尺度&#xff08;10m->250m&#xff09; 代码 var ext /* color: #d63000 *//* shown: false *//* displayProperties: [{"type": "rectangle"}] */ee.Geometry.Polygon([[[108.74625980473367, 28.562445155322063],[108.74625980473367, …

Nginx按指定格式记录访问日志以及利用logrotate做日志轮转

今天突然想起来一个日志的一个东西,因为拉项目无意中看到了日志文件的一些东西,现在不经常做后端了,加上其他的一些原因吧.有时候有些问题也没想太多,马马虎虎就过了,后来想想还是要记录一下这方面的处理过程吧: 一般我们作为开发人员关注的日志只是在应用程序层面的,我们称它…

2023五岳杯量子计算挑战赛数学建模思路+代码+模型+论文

目录 计算力网络&#xff08;CPN&#xff09;是一种新型的信息基础设施&#xff0c;完整论文代码见文末 问题描述 2.1 问题1 2.2 问题2 2.3 问题3 问题1的解答过程&#xff1a; 问题3的解答过程&#xff1a; 决策优化应用场景&#xff1a;人工智能模型超参数调优 背景信…

springboot基础(80):redis geospatial的应用

文章目录 前言redis geospatial如何从地图上获取经纬度springboot 的相关方法调用准备redis服务器引用的依赖预设位置的keyGEOADD 添加位置GEORADIUS 获取指定经纬度附件的停车场&#xff08;deprecated&#xff09;GEORADIUS 获取指定成员附件的停车场&#xff08;deprecated&…