C++ STL- list 的使用以及练习

目录

0.引言

1. list 介绍 

2. list 使用

2.1 构造函数

2.2 list iterator 的使用 

3 list capacity 

4. list element access 

5. list modifiers 

6. list 迭代器失效 

7. list 与vector 对vector

8. OJ 题讲解 

删除链表的倒数第 N  个节点:


0.引言

本篇博客我们将介绍 STL 中 list 的使用,由于list STL 接口函数与之前vector string 类似,我们在这里将不再详细赘述了,通过 OJ 题来练习 list 的实际使用。

1. list 介绍 

(1). list是可以在常数范围内在任意位置进行插入和删除的序列式容器,该容器可以前后双向迭代。

(2). list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。

(3). list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。

(4). 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。

(5). 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)。

2. list 使用

2.1 构造函数

构造函数:constructor说明
list (size_type n, const value_type& val = value_type()) 构造的list中包含n个值为val的元素
list() 构造空的list
list (const list& x) 拷贝构造函数
list (InputIterator first, InputIterator last) 用[first, last)区间中的元素构造list

2.2 list iterator 的使用 

函数声明说明
begin() + end()返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin() + rend()返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置

 这里可以将将迭代器理解成一个指针,该指针指向list中的某个节点。

(1).  begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

(2).  rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

3 list capacity 

函数声明说明
empty检测list是否为空,是返回true,否则返回false
size返回list中有效节点的个数

4. list element access 

函数声明说明
front返回list的第一个节点中值的引用
back返回list的最后一个节点中值的引用

5. list modifiers 

函数声明说明
push_front在list首元素前插入值为val的元素
pop_front删除list中第一个元素
push_back在list尾部插入值为val的元素
pop_back删除list中最后一个元素
insert在list position 位置中插入值为val的元素
erase删除list position位置的元素
swap交换两个list中的元素
clear清空list中的有效元素

6. list 迭代器失效 

迭代器失效即迭代器所指向的节点的无效,即该节 点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代 器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

int Array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
list<int> l(Array, Array + sizeof(Array) / sizeof(int));

auto it = l.begin();
while (it != l.end())
{
	// erase()接口被执行后,it所指向的节点已被删除,导致it迭代器无效,在下一次使用时,必须重新赋值
	l.erase(it);
	++it;
}

 

正确写法: 

int Array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
list<int> l(Array, Array + sizeof(Array) / sizeof(int));

auto It = l.begin();
while (It != l.end())
{
	// erase()接口被执行后,对It重新赋值
	l.erase(It++); // It = l.erase(It) -- 后置++先使用后自增
}

7. list 与vector 对vector

vectorlist
底层结构动态顺序表,一段连续空间 带头结点的双向循环链表
随机访问支持随机访问,访问某个元素效率O(1)不支持随机访问,访问某个元素 效率O(N)
插入和删除任意位置插入和删除效率低,需要搬移元素,时间复杂 度为O(N),插入时有可能需要增容,增容:开辟新空 间,拷贝元素,释放旧空间,导致效率更低 任意位置插入和删除效率高,不 需要搬移元素,时间复杂度为 O(1)
空间利用率底层为连续空间,不容易造成内存碎片,空间利用率 高,缓存利用率高 底层节点动态开辟,小节点容易 造成内存碎片,空间利用率低, 缓存利用率低
迭代器原生态指针 对原生态指针(节点指针)进行封装
迭代器失效在插入元素时,要给所有的迭代器重新赋值,因为插入 元素有可能会导致重新扩容,致使原来迭代器失效,删 除时,当前迭代器需要重新赋值否则会失效 插入元素不会导致迭代器失效, 删除元素时,只会导致当前迭代 器失效,其他迭代器不受影响
使用场景需要高效存储,支持随机访问,不关心插入删除效率 大量插入和删除操作,不关心随 机访问

8. OJ 题讲解 

删除链表的倒数第 N  个节点:

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 

 我们以示例为例来做分析,为完成题目要求,我们只需要将 3 指向 5 即可。

那么我们如何确定倒数第 n 个 节点的位置呢? 我i们只需要定义两个快慢指针,让快指针先走 n 步,然后再让快慢指针同时走,当快指针走到最后的一个节点时,那么慢指针指向的位置即为倒数第 n-1 个位置,刚好方便删除操作,最后为了方便返回头节点,我们可以提前开辟一个哨兵位,哨兵位指向头节点即可。

 

接着我们来看代码: 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
         ListNode* sentinel = new ListNode(0);  
         sentinel->next = head;
         ListNode* slow = sentinel;
         ListNode* fast = sentinel;
         while(n--)
            fast = fast->next;

         while(fast->next)
         {
            fast = fast->next;
            slow = slow->next;
         }
         slow->next = slow->next->next;

         return sentinel->next;  
    }
};

复杂度分析: 

快慢指针实则只遍历一次,时间复杂度 O(n), 只申请了有几个变量,空间复杂度 O(1) 。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

tcp/ip是什么意思,tcp/ip协议包含哪几层

TCP/IP是一种网络通信协议&#xff0c;它是互联网所采用的基本协议。TCP/IP协议是由美国国防部高级研究计划局&#xff08;ARPA&#xff09;在上世纪70年代设计开发的&#xff0c;经过多年发展和完善&#xff0c;已成为全球范围内最重要的网络通信协议之一。 首先&#xff0c;让…

python能做什么

python能做什么 Web开发&#xff1a;Python具有许多流行的Web框架&#xff0c;如Django和Flask&#xff0c;使得它成为Web开发的首选语言。它简洁、易于学习、且拥有丰富的生态系统&#xff0c;能够快速构建高性能的Web应用。 数据科学和机器学习&#xff1a;Python在数据科学…

Luminar Neo:重塑图像编辑新纪元,Mac与Win双平台畅享创意之旅

在数字时代的浪潮中&#xff0c;图像编辑软件已成为摄影师和设计师们不可或缺的创作工具。Luminar Neo&#xff0c;作为一款专为Mac与Windows双平台打造的图像编辑软件&#xff0c;正以其卓越的性能和创新的编辑功能&#xff0c;引领着图像编辑的新潮流。 Luminar Neo不仅继承…

Vue3更新Package.json版本号

由于我之前已经更新过了&#xff0c;下面的方法提示我已经是最新的了&#xff0c;记录一下&#xff0c;过段时间在测试一下 npm install -g vue/clivue upgrade

Python算法100例-4.2 列出真分数序列

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.拓展训练 1&#xff0e;问题描述 按递增顺序依次列出所有分母为40、分子小于40的最简分数。 2&#xff0e;问题分析 分子和分母只有公因数1的分数&…

《手把手教你》系列技巧篇(五十四)-java+ selenium自动化测试-上传文件-中篇(详细教程)

1.简介 在实际工作中&#xff0c;我们进行web自动化的时候&#xff0c;文件上传是很常见的操作&#xff0c;例如上传用户头像&#xff0c;上传身份证信息等。所以宏哥打算按上传文件的分类对其进行一下讲解和分享。 2.为什么selenium没有提供API&#xff1f; 想必小伙伴们或者…

【学习】软件测试人员如何设计出优秀的测试用例

在软件开发的过程中&#xff0c;测试用例如同工程质量的守护者&#xff0c;它们的存在确保了软件产品的稳定性和可靠性。然而&#xff0c;如何设计出优秀的测试用例&#xff0c;让其在千变万化的软件世界中独领风骚&#xff0c;成为众多测试工程师追寻的目标。本文将为你揭示其…

9、垃圾回收器

为什么分代GC算法要把堆分成年轻代和老年代&#xff1f;首先我们要知道堆内存中对象的特性&#xff1a; 系统中的大部分对象&#xff0c;都是创建出来之后很快就不再使用可以被回收&#xff0c;比如用户获取订单数据&#xff0c;订单数据返回给用户之后就可以释放了。老年代中…

小红书矩阵批量发布工具,一键发布笔记软件

昨日&#xff0c;我收到了一条充满渴望与期待的私信&#xff0c;来自一位小红书的矩阵账号博主。他手握多个账号&#xff0c;渴望寻找一款能够助力他批量发布笔记的神器&#xff0c;每日能够轻松达到百篇的发布量。这份迫切的需求&#xff0c;我深感体会&#xff0c;因为这正是…

看漫画学Python:有趣好玩

书籍介绍 Python是一门既简单又强大的编程语言&#xff0c;被广泛应用于数据分析、大数据、网络爬虫、自动化运维、科学计算和人工智能等领域。Python也越来越重要&#xff0c;成为国家计算机等级考试科目&#xff0c;某些中小学也开设了Python编程课程。本书秉承有趣、有料、…

个人周总结

个人周总结&#xff1a; 对于总体方向目标的完成&#xff0c;完成的不是很好&#xff0c;这周内的很多天都在游离&#xff0c;就是事情可能有需要做的&#xff0c;但是动力不很足&#xff0c;期间就是有点摆烂了。后面及时调整调整吧&#xff0c;有这种情况&#xff0c;一个原…

Qt实现简易的多线程TCP服务器(附源码)

目录 一.UI界面的设计 二.服务器的启动 三.实现自定义的TcpServer类 1.在widget中声明自定义TcpServer类的成员变量 2.在TcpServer的构造函数中对于我们声明的m_widget进行初始化&#xff0c;m_widget我们用于后续的显示消息等&#xff0c;说白了就是主界面的更新显示等 …

从人工智能入门到理解ChatGPT的原理与架构的第一天(First)(含机器学习特征工程详解)

目录 一.ChatGPT的发展历程 二.Attention is all you need 三.对于GPT-4的智能水平评估 四.大语言模型的技术演化 1.从符号主义到连接主义 2.特征工程 2.1数据探索 2.2数据清洗 2.3数据预处理 2.3.1无量纲化 2.3.1.1标准化 2.3.1.2区间缩放法 2.3.1.3标准化与归一…

Android开发简易登录界面

title: Android开发第四天 search: 2024-03-22 tags: Android开发 Android开发简易登录界面 文章目录 Android开发简易登录界面一、定义style样式二、完成 activity_main.xml 界面具体设计三、代码简述 背景 &#xff1a;在初学 android 开发的时候&#xff0c;为了尽量熟悉学…

RSTP环路避免实验(思科)

华为设备参考&#xff1a;RSTP环路避免实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 RSTP (Rapid Spanning Tree Protocol) 是从STP发展而来 • RSTP标准版本为IEEE802.1w • RSTP具备STP的所有功能&#xff0c;可以兼容STP运行 • RSTP和STP有所不同 减少了…

新书速览|Django 5企业级Web应用开发实战:视频教学版

掌握Django框架开发技能&#xff0c;实战投票应用系统和内容管理系统 本书内容 《Django 5企业级Web应用开发实战&#xff1a;视频教学版》精选当前简单、实用和流行的Django实例代码&#xff0c;帮助读者学习和掌握Django 5框架及其相关技术栈的开发知识。本书系统全面、内容…

深入解析MySQL的四种打开方式

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

伦敦金与纸黄金有什么区别?怎么选?

伦敦金与纸黄金都是与黄金相关的投资品种&#xff0c;近期黄金市场的上涨吸引了投资者的关注&#xff0c;那投资者想开户入场成为黄金投资者应该选择纸黄金还是伦敦金呢&#xff1f;两者有何区别呢&#xff1f;下面我们就来讨论一下。 伦敦金是一种起源于伦敦的标准化黄金交易合…

2015年认证杯SPSSPRO杯数学建模A题(第一阶段)绳结全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 A题 绳结 原题再现&#xff1a; 给绳索打结是人们在日常生活中常用的技能。对登山、航海、垂钓、野外生存等专门用途&#xff0c;结绳更是必不可少的技能之一。针对不同用途&#xff0c;有多种绳结的编制方法。最简单的绳结&#xff0c;有时称…

Go第三方框架--gin框架(一)

序言 Gin框架作为go语言使用最多的web框架&#xff0c;以其快速的响应速度和对复杂http路由配置的支持受到程序员和媛们的喜爱&#xff0c;几乎统治了web市场。但作为一名合格的程序员&#xff0c;要知其然更要知其所以然&#xff0c;不然八股文背的也没有啥意思。本着这个原则…