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

关于list

1、什么是list

list是一个带头结点的双向循环链表模版容器,可以存放任意类型,需要显式定义

2、list的使用

有了前面学习string和vector的基础,学习和使用list会方便很多,因为大部分的内容依然是高度重合的。

与顺序表不同,链表是以结点形式进行链接和存储,其地址并不是连续的,因此进行插入和删除操作不需要进行大量的数据挪动,只需要改变指针的指向即可,方便很多。

使用push_back()和push_front()可以分别实现尾插和头插

    list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_front(5);lt.push_front(6);for (auto e : lt){cout << e << " ";}cout << endl;

也可以使用insert实现在某一位置的插入,erase实现在某一位置的删除

    lt.insert(lt.begin(), 9);for (auto e : lt){cout << e << " ";}cout << endl;lt.erase(lt.begin());for (auto e : lt){cout << e << " ";}cout << endl;

然而由于迭代器的失效问题,erase会返回被删除元素的下一个位置,因此,当进行连续删除时,我们可以使用迭代器来直接对此返回值进行接收来实现

	list<int>::iterator it = ++lt.begin();while (it != lt.end()){cout << (*it) << " ";it=lt.erase(it);}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;

同时,由于list底层结构的不同,不能像string和vector一样去实现迭代器,因为string和vector在底层结构中是连续的,可以直接用指针去访问得到相应位置的元素内容,对指针进行++或者--操作又可以直接到达下一位置或者前一位置,list中存放的是一个一个不连续的结点,对迭代器的实现时需要进行相应的重载,使用也会受限,比如在上述代码中就无法使用lt.begin()+3等,更多内容在进行list的模拟实现中可以得到更多的体会

reverse()用于逆置,库里有实现公用的reverse,不过list里面也有提供自己的逆置,如果使用公用的则需要使用两个参数指定逆置的范围,如果使用的是自己的逆置则不需要传参

    reverse(lt.begin(), lt.end());lt.reverse();for (auto e : lt){cout << e << " ";}cout << endl;

对于排序,之前的vector可以直接调用库中的sort()函数实现排序,实际sort()排序使用的是快排进行排序,而对于数组这种结构来说快排会很方便,而对于链表来说则比较困难,代价较高,因此库中的排序函数并不能对list进行排序,list内部自己有实现一个排序,可以进行使用并完成排序。不过对于list来说,排序始终代价较大,如果需要频繁使用排序应该使用其他的结构来存放数据,所以库里的sort()函数实质上也是对程序员的一种约束。

	//sort(lt.begin(), lt.end());lt.sort();for (auto e : lt){cout << e << " ";}cout << endl;

find()函数是库里实现的公用函数,list也可以使用,同时会返回寻找元素的位置

	auto it=find(lt.begin(), lt.end(), 3);cout << *it;

splice()可以用于将某一部分的内容转移至其他list中,也可以转移给自身的其他地方

	list<int> lt2 = { 10,20,30 };//全部转移//lt2.splice(lt2.begin(), lt);//部分转移//lt2.splice(lt2.begin(), lt, ++lt.begin());//转移某一位置的内容lt2.splice(lt2.begin(), lt,++lt.begin(),--lt.end());//转移某一段位置的内容//lt2.splice(++lt2.begin(), lt2, lt2.begin(), lt2.end());for (auto e : lt){cout << e << " ";}cout << endl;for (auto e : lt2){cout << e << " ";}cout << endl;lt2.splice(lt2.begin(), lt2, ++lt2.begin(), lt2.end());for (auto e : lt2){cout << e << " ";}cout << endl;

以上就是list的一些较常用的使用,那么在对list及其使用都有了解后就可以进行模拟实现

3、list的模拟实现

不得不说,我觉得list的实现比前面的string和vector的实现难很多,主要是迭代器的原因会上很大难度,很难以理解,所以直到勉强实现出来以后也还是处于一个似懂非懂的状态里,希望后面能继续加强自己的技术,实现轻松手撕

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;namespace bit
{template<class T>struct ListNode{ListNode(const T& val = T()):_prev(nullptr),_next(nullptr),_val(val){}ListNode* _prev;ListNode* _next;T _val;};template<class T,class Ref,class Ptr>struct List_iterator{typedef ListNode<T> Node;typedef List_iterator<T, Ref,Ptr> Self;Node* _node;List_iterator(Node* node):_node(node){}Ref operator*(){return _node->_val;}Ptr operator->(){return &_node->_val;}Self& operator++(){_node = _node->_next;return *this;}Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}Self& operator--(){_node = _node->_prev;return *this;}Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}bool operator!=(const Self& it){return _node != it._node;}bool operator==(const Self& it){return _node == it._node;}};template<class T>class List{public:typedef ListNode<T> Node;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;}List(){empty_init();}//list(const list<T>& lt)//{//	empty_init();//	for (auto& e : lt)//	{//		push_back(e);//		_size++;//	}//}size_t size(){return _size;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_head->_val = 0;_size = 0;}void push_back(const T& x){insert(end(), x);//Node* newnode = new Node;//_head->_prev->_next = newnode;//newnode->_prev = _head->_prev;//newnode->_next = _head;//_head->_prev = newnode;//newnode->_val = x;//_size++;}void push_front(const T& x){insert(++end(), x);//Node* newnode = new Node;//_head->_next->_prev = newnode;//newnode->_next = _head->_next;//_head->_next = newnode;//newnode->_prev = _head;//newnode->_val = x;//_size++;}void pop_back(){erase(--end());}void pop_front(){erase(++end());}void clear(){iterator it = begin();while (it != end()){it = erase(it);}_size = 0;}iterator insert(iterator pos,const T& x){Node* newnode = new Node;Node* cur = pos._node;newnode->_prev = cur->_prev;cur->_prev->_next = newnode;cur->_prev = newnode;newnode->_next = cur;newnode->_val = x;_size++;return newnode;}iterator erase(iterator pos){Node* cur = pos._node;cur->_next->_prev = cur->_prev;cur->_prev->_next = cur->_next;pos._node = cur->_next;delete cur;_size--;return pos;}void swap(List<T> tmp){std::swap(_head, tmp._head);std::swap(_size, tmp._size);}List<T>& operator=(List<T> tmp){swap(tmp);return *this;}List(const List<T>& lt){empty_init();//const_iterator it = lt.begin();//while (it != lt.end())//{//	push_back(*(it));//	it++;//}//_size = lt._size;for (auto& e : lt){push_back(e);}}~List(){clear();delete _head;_head = nullptr;}private:Node* _head;size_t _size;};
}

http://www.xdnf.cn/news/1126279.html

相关文章:

  • 微信小程序入门实例_____从零开始 开发一个每天记账的微信小程序
  • 【GPIO】从STM32F103入门GPIO寄存器
  • 153.在 Vue 3 中使用 OpenLayers + Cesium 实现 2D/3D 地图切换效果
  • 淘宝扭蛋机小程序开发:重构电商娱乐化体验的新范式
  • Kruskal重构树
  • Linux操作系统从入门到实战(九)Linux开发工具(中)自动化构建-make/Makefile知识讲解
  • 12.6 Google黑科技GShard:6000亿参数MoE模型如何突破显存限制?
  • 导出内存溢出案例分析
  • 学习秒杀系统-实现秒杀功能(商品列表,商品详情,基本秒杀功能实现,订单详情)
  • JavaScript认识+JQuery的依赖引用
  • ethers.js-8-bigNmber和callstatic模拟
  • 2025年最新香港站群服务器租用价格参考
  • 探索阿里云ESA:开启边缘安全加速新时代
  • 基于Ruoyi和PostgreSQL的统一POI分类后台管理实战
  • 论文阅读:arxiv 2025 A Survey on Data Contamination for Large Language Models
  • 从12kW到800V,AI服务器电源架构变革下,功率器件如何解题?
  • redisson 设置了过期时间,会自动续期吗
  • 【网络安全】大型语言模型(LLMs)及其应用的红队演练指南
  • 经典排序算法之希尔排序
  • docker 方式gost代理搭建以及代理链实施
  • HTTP常见误区
  • 具身智能零碎知识点(六):VAE 核心解密:重参数化技巧(Reparameterization Trick)到底在干啥?
  • 第二章 OB 存储引擎高级技术
  • JavaScript进阶篇——第四章 解构赋值(完全版)
  • IT岗位任职资格体系及发展通道——研发岗位任职资格标准体系
  • 进程探秘:从 PCB 到 fork 的核心原理之旅
  • 从零开始的云计算生活——第三十二天,四面楚歌,HAProxy负载均衡
  • 测试tcpdump,分析tcp协议
  • JAVA学习笔记 使用notepad++开发JAVA-003
  • Bootstrap-HTML(七)Bootstrap在线图标的引用方法