当前位置: 首页 > news >正文

【C++】list相关接口及模拟实现

一、介绍

List是一个序列容器,允许在序列任意位置插入和删除数据。
它经常被实现为双向链表。(可以直接理解为双向链表)

相关文档介绍:
在这里插入图片描述

二、相关接口

与之前讲的vector容器不同的是,vector中的数据在内存中有连续的存储空间,而list中的数据在内存中是不连续存放的。两者接口用法类似,这里便不一一列举说明了。
常用接口:
在这里插入图片描述
文档:list相关接口
具体用法可参考vector章节内容:vector容器常用接口及使用

三、模拟实现

list底层是双向链表,需要使用链表知识进行模拟实现。

(1)定义结点

template <class T>
struct list_node  //struct默认公有,class默认私有
{T _data;list_node<T>* _prev; //前驱list_node<T>* _next; //后继//构造函数,初始化列表list_node(const T& x = T()):_data(x),_prev(nullptr),_next(nullptr){}
};

(2)模拟迭代器

//迭代器
template<typename T, typename Ref, typename Ptr>
struct list_iterator
{typedef list_node<T> Node;typedef list_iterator<T, Ref, Ptr> Self;Node* _node;list_iterator(Node* node):_node(node){}//运算符重载//T& operator*()Ref operator*(){return _node->_data;}//T* operator->()Ptr operator->(){return &_node->_data;}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; }bool operator!=(const Self& s) const{return _node != s._node;}bool operator==(const Self& s) const{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; //const迭代器iterator begin(){/*iterator it(_head->_next);return it;*/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->_prev = _head;_head->_next = _head;_size = 0;}//构造list(){empty_init();}//拷贝构造lt2(lt1)list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}//析构~list(){clear();delete _head;_head = nullptr;}//清除除哨兵位以外的所有节点void clear(){auto it = begin();while (it != end()){it = erase(it);//防止迭代器失效,erase()会返回下一个位置的迭代器。}}//尾插void push_back(const T& x){//Node* newnode = new Node(x);//Node* tail = _head->_prev;//尾节点//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;//_size++;insert(end(), x);_size++;}//头插void push_front(const T& x){insert(begin(), x);_size++;}//插入void insert(iterator pos, const T& x) //在it位置之前插入x{Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);//prev newnode cur 在prev和cur中间插入newnodecur->_prev = newnode;newnode->_next = cur;newnode->_prev = prev;prev->_next = newnode;_size++;}//尾删void pop_back(){erase(--end());}//头删void pop_front(){erase(begin());}//删除iterator erase(iterator pos){assert(pos != end());//不能删哨兵位头结点Node* prev = pos._node->_prev;Node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;--_size;return next;}size_t size() const{return _size;}bool empty() const{return _size == 0;}private:Node* _head;//头结点size_t _size;
};

(4)打印

//打印
template<class Container>
void print_container(const Container& con)
{typename Container::const_iterator it = con.begin();//auto it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;
}

(5)完整代码

#include<assert.h>
#include<iostream>
using namespace std;
namespace jyan
{template <class T>struct list_node  //struct默认公有,class默认私有{T _data;list_node<T>* _prev; //前驱list_node<T>* _next; //后继list_node(const T& x = T()):_data(x),_prev(nullptr),_next(nullptr){}};//迭代器template<typename T, typename Ref, typename Ptr>struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, Ref, Ptr> Self;Node* _node;list_iterator(Node* node):_node(node){}//T& operator*()Ref operator*(){return _node->_data;}//T* operator->()Ptr operator->(){return &_node->_data;}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; }bool operator!=(const Self& s) const{return _node != s._node;}bool operator==(const Self& s) const{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; //const迭代器iterator begin(){/*iterator it(_head->_next);return it;*/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->_prev = _head;_head->_next = _head;_size = 0;}//构造list(){empty_init();}//拷贝构造lt2(lt1)list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}~list(){clear();delete _head;_head = nullptr;}//清除除哨兵位以外的所有节点void clear(){auto it = begin();while (it != end()){it = erase(it);//防止迭代器失效,erase()会返回下一个位置的迭代器。}}//尾插void push_back(const T& x){//Node* newnode = new Node(x);//Node* tail = _head->_prev;//尾节点//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;//_size++;insert(end(), x);_size++;}//头插void push_front(const T& x){insert(begin(), x);_size++;}//插入void insert(iterator pos, const T& x) //在it位置之前插入x{Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);//prev newnode cur 在prev和cur中间插入newnodecur->_prev = newnode;newnode->_next = cur;newnode->_prev = prev;prev->_next = newnode;_size++;}//尾删void pop_back(){erase(--end());}//头删void pop_front(){erase(begin());}//删除iterator erase(iterator pos){assert(pos != end());//不能删哨兵位头结点Node* prev = pos._node->_prev;Node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;--_size;return next;}size_t size() const{return _size;}bool empty() const{return _size == 0;}private:Node* _head;//头结点size_t _size;};//打印template<class Container>void print_container(const Container& con){// const iterator -> 迭代器本身不能修改// const_iterator -> 指向内容不能修改typename Container::const_iterator it = con.begin();//auto it = con.begin();while (it != con.end()){cout << *it << " ";++it;}cout << endl;}//代码测试void test_1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;}void test_2(){list<int> lt;lt.push_front(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);/*list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;*/print_container(lt);lt.pop_back();lt.pop_front();print_container(lt);/*it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;*/}void test_3(){std::list<int> lt = { 1,2,3,4,5,6 };print_container(lt);}
}
int main()
{jyan::test_3();return 0;
}

四、谢谢观看!

http://www.dtcms.com/a/474517.html

相关文章:

  • Vue-MVVM 模型
  • 网站需要什么费用高端品牌网站有哪些
  • Emacs折腾日记(三十二)——org mode的基本美化
  • 从数据混沌到智能驱动:非结构化数据中台的技术实践与方法论指南
  • 什么是自相关分析(ACF)?
  • Web前端开发,新手入门指南
  • 织梦增加网站英文名称百度商桥怎么和网站
  • Paper2Agent:将科研论文转化为可交互的AI智能体工具项目
  • 静态网页 vs 动态网页:爬虫该如何选择抓取策略?
  • AI/CICD/Next/React NativeTaro内容
  • godot 通过 GDExtension 配置 C++ 开发环境
  • XMLHttpRequest对象
  • 广州市外贸网站建设内容管理系统开发
  • 带你了解STM32:SPI通信(软件部分)
  • 标量子查询优化(二)
  • 网站建设的客户都在哪里Wordpress西联
  • ppo dino 多余尺寸删除ai 思路2 绕过cad软件
  • 【LeetCode】66. 加一
  • 日志1--时间戳类型设计
  • 手机网站 qq代码免费app制作工具
  • MyBatis-Plus 全方位使用指南:从基础 CRUD 到复杂查询
  • avalonia的hello示例及mvvm实现
  • 天津网站建设优化如何建网站费用多少
  • 网站建设泉州效率网络企业网站建设基本原则
  • 41.Shell Case选择 While循环
  • 基于单片机的智能水箱温度液位控制系统设计
  • 数字化转型—AI+制造业的十大应用场景
  • Java-集合练习
  • 新民正规网站建设价格咨询广州app开发价格表
  • 适合用struts2做的网站钦州教育论坛网站建设