前言list的认识

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

1 list的构造
常用的构造函数

default (1)

默认构造)

explicit list (const allocator_type& alloc = allocator_type());

      fill (2)

 n个val值填充

explicit list (size_type n, const value_type& val = value_type(),const allocator_type& alloc = allocator_type());

range (3)

   迭代器构造

template <class InputIterator>list (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type());

copy (4)

拷贝构造

list (const list& x);
参考代码 : 
   
void print_list(list<int>& list1)
{list<int>::iterator it = list1.begin();while (it != list1.end()){cout << *it;it++;}cout << endl;}
void construct_test()
{list<int>list_1;// 空构造list<int>list_2(20,0);// n  vallist<int>::iterator it = list_2.begin();  // 迭代器构造 list<int> th(list_2.begin(),list_2.end());// 不支持的写法 list<int> th(list_2.begin(),list_2.begin()+4);// 因为list的迭代器不支持随机访问哦 其实本质上是因为只给迭代器封装了++的操作 int arr[] = {1,2,3,4,5,6};list<int>four(arr,arr+4);// 这也是迭代器构造 数组肯定是可以通过下标 随机访问啦 // 拷贝构造//list<int> five = four;list<int> five(four);print_list(five);}

2. list的迭代器 

    list的图解 

迭代器的理解:

  
  这个迭代器的内部封装可以大致这么理解:
    肯定是对node的操作,封装node的移动,有++,--以及!=   判断俩个迭代器是否相等就这样就很常见,封装的目的很简单,就是为了统一容器的操作哦!。
    后期博客我会更新其中的模拟实现这是很有意思的:
   内部是没有封装+某个数的 
   所以之前例子中指出 像这样的 list<int>::iterator(it,it+3);  是不被允许的哦!
总之因为list的底层容器是双向链表,每个节点地址之间是不连续的,所以我们为了统一容器操作就封装迭代器了。
迭代器使用:代码实例:
void iterator_test() {int arr[] = { 1,2,3,4,5,6 };list<int>four(arr, arr + 5);// 用迭代器遍历four这个链表list<int>::iterator it = four.begin();// 正向迭代器list<int>::reverse_iterator rit = four.rbegin();// 反向迭代器while (it != four.end()){cout << *it;it++;}cout << endl;while (rit != four.rend()){cout << *rit;rit++;}cout << endl;}
输出:12345   
           54321

doubly list的图解

   这里只标出了 node之间指针的关系,这里值得注意的就是如何实现双向循环的,就是创建一个头节点,头节点作用就是用来很方便的实现增删查改(减少判空这个策略数据结构中可以多了解理解) 总之就是让头节点的pre指向尾节点,尾节点的next指向头节点。 总之头节点是不存放有效数据的! 所以下面我说说迭代器遍历的问题!

 list迭代器遍历的理解: 

      显然 list<T>iterator:: begin 指向的是头节点的下一个位置,node结构体中总是存放的是头节点,所以需要遍历的时候需要总是从头节点开始一一遍历,而不是随机访问。 
    判断到尾部的方法有很多一个是根据size,以及cur节点的遍历到了头节点了。

3. list element access(元素获取)

     list的获取常用的就是一个是front  和 back  双向链表根据头节点实现起来很方便的。

     

3.1 reference front()  和reference back的使用
        这个list的front的成员函数,简单来说就是返回一个头节点的元素引用。 
这里的referrence其实是一个typedef,这个在库里面实现是很常见的  可以这样理解:
typedef reference T;
  back同理如上。
   
// list::front
#include <iostream>
#include <list>int main ()
{std::list<int> mylist;mylist.push_back(77);mylist.push_back(22);// now front equals 77, and back 22mylist.front() -= mylist.back();std::cout << "mylist.front() is now " << mylist.front() << '\n';return 0;
}

输出: 55

4. list modified 元素修改

    list常用的修改方面的有:  头插,头删,尾删,尾插,还有指定位置删除,和指定位置插入,还有指定尾插删除, 以及swap (经常被用于去写构造函数的还有拷贝构造)

4.1 push_front 和pop_front

实现:
// list::push_front
#include <iostream>
#include <list>int main ()
{std::list<int> mylist (2,100);         // two ints with a value of 100mylist.push_front (200);mylist.push_front (300);std::cout << "mylist contains:";for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

实现:
// list::pop_front
#include <iostream>
#include <list>int main ()
{std::list<int> mylist;mylist.push_back (100);mylist.push_back (200);mylist.push_back (300);std::cout << "Popping out the elements in mylist:";while (!mylist.empty()){std::cout << ' ' << mylist.front();mylist.pop_front();}std::cout << "\nFinal size of mylist is " << mylist.size() << '\n';return 0;
}

4.2 push_back和pop_front 

    尾插和尾删 返回值都是void注意哦
  
// list::push_back
#include <iostream>
#include <list>int main ()
{std::list<int> mylist;int myint;std::cout << "Please enter some integers (enter 0 to end):\n";do {std::cin >> myint;mylist.push_back (myint);} while (myint);std::cout << "mylist stores " << mylist.size() << " numbers.\n";return 0;
}

 

// list::pop_back
#include <iostream>
#include <list>int main ()
{std::list<int> mylist;int sum (0);mylist.push_back (100);mylist.push_back (200);mylist.push_back (300);while (!mylist.empty()){sum+=mylist.back();mylist.pop_back();}std::cout << "The elements of mylist summed " << sum << '\n';return 0;
}

4.3 insert

  在指定位置(用迭代器哦) 插入一个元素,
     插入n个val 在指定位置
  在指定位置插入一个范围迭代器区间的元素

void insert_test() {int arr[] = { 1,2,3,4,5 };//    1  2  3  4  5int arr1[] = { 11,12,13,14,15 };//    11  12  13  14  15vector<int>v1(arr,arr+5);list<int> mylist(arr1,arr1+5);     //     !list<int>::iterator it = mylist.begin();it++;mylist.insert(it,10);// 迭代器可能存在失效的问题 所以这里一定要给it重赋值   print_list(mylist);// n valit = mylist.begin();it++;mylist.insert(it, 10,1);print_list(mylist);//  范围插入it = mylist.begin();it++;mylist.insert(it, v1.begin()+2, v1.end());print_list(mylist);}
输出:11 10 12 13 14 15
11 1 1 1 1 1 1 1 1 1 1 10 12 13 14 15
11 3 4 5 1 1 1 1 1 1 1 1 1 1 10 12 13 14 15

4.4 erase 删除

 传递的参数是list的迭代器,指定位置删除和指定的迭代器范围区间的元素删除。

std:: iterator& advance(iterator,len) 这是库里的移动迭代器的函数

// erasing from list
#include <iostream>
#include <list>int main ()
{std::list<int> mylist;std::list<int>::iterator it1,it2;// set some values:for (int i=1; i<10; ++i) mylist.push_back(i*10);// 10 20 30 40 50 60 70 80 90it1 = it2 = mylist.begin(); // ^^advance (it2,6);            // ^                 ^++it1;                      //    ^              ^it1 = mylist.erase (it1);   // 10 30 40 50 60 70 80 90//    ^           ^it2 = mylist.erase (it2);   // 10 30 40 50 60 80 90//    ^           ^++it1;                      //       ^        ^--it2;                      //       ^     ^mylist.erase (it1,it2);     // 10 30 60 80 90//        ^std::cout << "mylist contains:";for (it1=mylist.begin(); it1!=mylist.end(); ++it1)std::cout << ' ' << *it1;std::cout << '\n';return 0;
}

5. 迭代器失效问题

   我们之前说过迭代器的实现可以理解为一个封装了node的移动和判断的类。  这里的数据存放是node,所以本质上还是用node*指向了一个节点,所以在list中只要该节点不删除,这个节点依然存在。 
  在list中插入不会导致迭代器失效,因为这个节点并没有被销毁(vector中的迭代器失效是因为他们的内存是连续的,当扩容的时候可能导致旧内存被销数据被移动到新内存)但是list的底层是双向循环链表,内存之间都是用指针(地址)连接起来的,不用在乎是否连续,你不主动销毁内存是不会被销毁的。
   所以只有当删除的时候才会被销毁。

谈谈erase和insert的返回值

   erase:
iterator erase (iterator position);
iterator erase (iterator first, iterator last); 

insert:

single element (1)
iterator insert (iterator position, const value_type& val);
fill (2)
void insert (iterator position, size_type n, const value_type& val);
range (3)
template <class InputIterator>void insert (iterator position, InputIterator first, InputIterator last);
insert:大体上分为两,一种是插入一个元素,一个是插入多个元素。
返回值:简单理解就是返回插入元素后的下一个位置的元素
erase则是返回删除元素的下一个位置
处理迭代器失效: 就是重新赋值给迭代器:
错误实例 没有重新赋值 
修正: 
   代码: 
void TestListIterator1()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给//其赋值it =l.erase(it);++it;}
}

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

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

相关文章

本地WSL部署接入 whisper + ollama qwen3:14b 总结字幕

1. 实现功能 M4-1 接入 whisper ollama qwen3:14b 总结字幕 自动下载视频元数据如果有字幕&#xff0c;只下载字幕使用 ollama 的 qwen3:14b 对字幕内容进行总结 2.运行效果 source /root/anaconda3/bin/activate ytdlp &#x1f50d; 正在提取视频元数据… &#x1f4dd; 正在…

《Linux运维总结:Shell脚本高级特性之变量间接调用》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;Linux运维实战总结 一、变量间接调用 在Shell脚本中&#xff0c;变量间接调用是一种高级特性&#xff0c;它允许你通过另一个变量的值来动态地访问…

ABP VNext + Akka.NET:高并发处理与分布式计算

ABP VNext Akka.NET&#xff1a;高并发处理与分布式计算 &#x1f680; 用 Actor 模型把高并发写入“分片→串行化”&#xff0c;把锁与竞态压力转回到代码层面的可控顺序处理&#xff1b;依托 Cluster.Sharding 横向扩容&#xff0c;Persistence 宕机可恢复&#xff0c;Strea…

[激光原理与应用-250]:理论 - 几何光学 - 透镜成像的优缺点,以及如克服缺点

透镜成像是光学系统中应用最广泛的技术&#xff0c;其通过折射原理将物体信息转换为图像&#xff0c;但存在像差、环境敏感等固有缺陷。以下是透镜成像的优缺点及针对性改进方案&#xff1a;一、透镜成像的核心优点高效集光能力透镜通过曲面设计将分散光线聚焦到一点&#xff0…

测试匠谈 | AI语音合成之大模型性能优化实践

「测试匠谈」是优测云服务平台倾心打造的内容专栏&#xff0c;汇集腾讯各大产品的顶尖技术大咖&#xff0c;为大家倾囊相授开发测试领域的知识技能与实践&#xff0c;让测试工作变得更加轻松高效。 本期嘉宾介绍 Soren&#xff0c;腾讯TEG技术事业群质量工程师&#xff0c;负责…

用天气预测理解分类算法-从出门看天气到逻辑回归

一、生活中的决策难题&#xff1a;周末郊游的「天气判断」 周末计划郊游时&#xff0c;你是不是总会打开天气预报反复确认&#xff1f;看到 "25℃、微风、无雨" 就兴奋收拾行李&#xff0c;看到 "35℃、暴雨" 就果断取消计划。这个判断过程&#xff0c;其…

HTTPS服务

HTTPS服务 一、常见的端口 http ------ 80 明文 https ------ 443 数据加密 dns ------ 53 ssh ------ 22 telent ------ 23 HTTPS http ssl或者tls &#xff08;安全模式&#xff09; 二、原理&#xff1a; c&#xff08;客户端…

【Android笔记】Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)

Android 自定义 TextView 实现垂直渐变字体颜色&#xff08;支持 XML 配置&#xff09; 在 Android UI 设计中&#xff0c;字体颜色的渐变效果能让界面看起来更加精致与现代。常见的渐变有从左到右、从上到下等方向&#xff0c;但 Android 的 TextView 默认并不支持垂直渐变。…

CANopen Magic调试软件使用

一、软件安装与硬件连接1.1 系统要求操作系统&#xff1a;Windows 7/10/11 (64位)硬件接口&#xff1a;支持Vector/PEAK/IXXAT等主流CAN卡推荐配置&#xff1a;4GB内存&#xff0c;2GHz以上CPU1.2 安装步骤运行安装包CANopen_Magic_Setup.exe选择安装组件&#xff08;默认全选&…

前端css学习笔记3:伪类选择器与伪元素选择器

本文为个人学习总结&#xff0c;如有谬误欢迎指正。前端知识众多&#xff0c;后续将继续记录其他知识点&#xff01; 目录 前言 一、伪类选择器 1.概念 2.动态选择器&#xff08;用户交互&#xff09; 3.结构伪类 &#xff1a;first-child&#xff1a;选择所有兄弟元素的…

深入探索 PDF 数据提取:PyMuPDF 与 pdfplumber 的对比与实战

在数据处理和分析领域&#xff0c;PDF 文件常常包含丰富的文本、表格和图形信息。然而&#xff0c;从 PDF 中提取这些数据并非易事&#xff0c;尤其是当需要保留格式和颜色信息时。幸运的是&#xff0c;Python 社区提供了多个强大的库来帮助我们完成这项任务&#xff0c;其中最…

Springboot注册过滤器的三种方式(Order 排序)

一、使用 Component Order&#xff08;简单但不够灵活&#xff09; 适用于全局过滤器&#xff0c;无需手动注册&#xff0c;Spring Boot 会自动扫描并注册。 Component Order(1) // 数字越小&#xff0c;优先级越高 public class AuthFilter implements Filter {Autowired /…

电脑硬件详解

前几天我的风扇转的很快&#xff0c;而且cpu占用率很高&#xff0c;然后我在想怎么回事&#xff0c;然后就浅浅研究了一下电脑的硬件。 笔记本主板&#xff1a; 台式机主板&#xff1a; 图1&#xff1a; 图2&#xff1a; 电脑硬件详解 电脑的硬件是组成计算机系统的物理设…

力扣47:全排列Ⅱ

力扣47:全排列Ⅱ题目思路代码题目 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 思路 又是任意顺序和所有不重复的排列&#xff0c;显而易见我们要使用回溯的办法。 首先是回溯的结束条件即新数组的长度等于nums的长度。这道题的难点…

学习笔记091——如何实现web登录时,密码复杂度校验?(后端)

1、创建工具类 /*** 密码复杂度校验* param password 密码*/ public static void validatePassword(String password) {// 至少8位if (password.length() < 8) {throw new IllegalArgumentException("密码长度至少为8位");}// 包含大小写字母if (!password.matche…

雪花算法snowflake分布式id生成原理详解,以及对解决时钟回拨问题几种方案讨论

一、前言在日趋复杂的分布式系统中&#xff0c;数据量越来越大&#xff0c;数据库分库分表是一贯的垂直水平做法&#xff0c;但是需要一个全局唯一ID标识一条数据或者MQ消息&#xff0c;数据库id自增就显然不能满足要求了。因为场景不同&#xff0c;分布式ID需要满足以下几个条…

【PCB设计经验】去耦电容如何布局?

0805 和 0603 以及更小 封装的电容用作于对中高频的去耦,其摆放位置是有要求的: 一、建议尽可能的靠近主控芯片的 电源管脚放置。 二、使用较宽和短的引线连接到电源和地过孔可以采用如下 图 4–1 中的图 ( 2 )、( 3)、 ( 4 )任意一种方式,避免使用长线或者较细的…

自动化运维实验

目录 一、实验拓扑 二、实验目的 三、实验步骤 实验思路&#xff1a; 代码部分&#xff1a; 四、实验结果&#xff1a; 一、实验拓扑 二、实验目的 利用python脚本&#xff0c;在本地&#xff0c;或者虚拟机里实现&#xff0c;设备CRC数量统计&#xff0c;并输出成表格 三、实验…

Wed前端第二次作业

一、作业1&#xff1a;完成自己学校的官网&#xff0c;动忘内容直接贴&#xff0c;至少三个不同的页面1、界面1&#xff08;1&#xff09;相关代码<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&quo…

第5节 大模型分布式推理通信优化与硬件协同

前言 在分布式推理中,多设备(如GPU、CPU)之间的数据传输(通信)是连接计算的“桥梁”。如果通信效率低下,即使单设备计算能力再强,整体性能也会大打折扣。想象一下:如果工厂之间的物流卡车跑得比生产速度还慢,再多的工厂也无法提高整体产量。 本节将从最基础的单设备内…