【C++入门到精通】C++入门 —— list (STL)


阅读导航

  • 前言
  • 一、list简介
    • 1.概念
    • 2.特点
  • 二、list的使用
    • 1.list的构造
    • 2.常见的操作
      • ⭕std::list类型的增、删、查、改
  • 三、list与vector的对比
  • 温馨提示

前言

文章绑定了VS平台下std::list的源码,大家可以下载了解一下😍

前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象’ ,以及学习了几个STL的结构也相信大家都掌握的不错,接下来博主将会带领大家继续学习有关C++比较重要的知识点—— list(STL)。下面话不多说坐稳扶好咱们要开车了😍

一、list简介

1.概念

std::list是C++标准库中的双向链表容器。(这里有官方介绍链接) 它支持在任意位置进行快速插入和删除操作,并且在需要对元素进行频繁的插入和删除操作时,通常比std::vector更高效。std::list的元素不是在连续内存中存储,而是通过指针相互连接在一起。
list的模型化图像

2.特点

  1. 双向访问:std::list的元素可以通过双向迭代器从前向后或者从后向前进行访问。

  2. 插入和删除操作高效:由于std::list的元素是通过指针连接在一起的,插入和删除操作只需要修改相邻元素的指针,因此在任意位置进行插入和删除操作的时间复杂度是O(1)。

  3. 不支持随机访问:由于std::list的元素不是在连续内存中存储的,因此不能通过下标来随机访问元素。如果需要随机访问元素,可以考虑使用std::vector或者std::array。

  4. 内存占用相对较大:由于每个元素都需要额外的指针来连接其他元素,std::list的内存占用相对较大。

二、list的使用

list 中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口

1.list的构造

std::list类提供了多个构造函数,用于创建和初始化std::list对象。官方链接点这里跳转 下面是常用的构造函数列表:

  1. 默认构造函数:

    std::list<T> myList;
    

    创建一个空的std::list对象,其中T是元素的类型。

  2. 带有容量参数的构造函数:

    std::list<T> myList(size, value);
    

    创建一个包含size个元素的std::list对象,每个元素的值都是value。

  3. 区间构造函数:

    std::list<T> myList(first, last);
    

    创建一个std::list对象,其中包含[first, last)区间的元素。first和last是输入迭代器,用于指定要拷贝到新std::list中的元素范围。

  4. 拷贝构造函数:

    std::list<T> myList(otherList);
    

    创建一个std::list对象,其中包含与otherList相同的元素。这将执行深拷贝,即将otherList中的元素复制到新的std::list对象中。

  5. 移动构造函数:

    std::list<T> myList(std::move(otherList));
    

    创建一个std::list对象,并从其他std::list对象otherList中移动元素到新的std::list对象中。在移动构造函数后,otherList将为空。

注意:上述构造函数中的T表示元素的类型,可以是任何有效的C++类型

#include <list>int main() {// 默认构造函数std::list<int> myList;// 带有容量参数的构造函数std::list<int> myList2(5, 10); // 包含5个值为10的元素// 区间构造函数int arr[] = {1, 2, 3, 4, 5};std::list<int> myList3(std::begin(arr), std::end(arr)); // 包含数组arr的元素// 拷贝构造函数std::list<int> myList4(myList2);// 移动构造函数std::list<int> myList5(std::move(myList4)); // myList4将为空return 0;
}

这些是std::list常用的构造函数示例。你可以根据自己的需求选择适当的构造函数来创建std::list对象。

2.常见的操作

⭕std::list类型的增、删、查、改

  1. 插入元素:

    • push_back(value):在列表的末尾插入一个元素。
    • push_front(value):在列表的开头插入一个元素。
    • insert(pos, value):在指定位置pos之前插入一个元素。
  2. 删除元素:

    • pop_back():删除列表末尾的元素。
    • pop_front():删除列表开头的元素。
    • erase(pos):删除指定位置pos处的元素。
    • erase(first, last):删除从[first, last)范围内的所有元素。
  3. 访问元素:

    • front():返回列表的第一个元素的引用。
    • back():返回列表的最后一个元素的引用。
  4. 迭代器操作:

    • begin():返回指向列表第一个元素的迭代器。
    • end():返回指向最后一个元素之后位置的迭代器。
    • rbegin():返回指向列表最后一个元素的逆向迭代器。
    • rend():返回指向第一个元素之前位置的逆向迭代器。
  5. 大小和清空操作:

    • size():返回列表中元素的数量。
    • empty():检查列表是否为空。
    • clear():清除列表中的所有元素。
  6. 修改元素:

    • assign(first, last):用[first, last)范围内的元素替换列表的内容。
    • assign(n, value):用n个值为value的元素替换列表的内容。
    • resize(count):改变列表的大小,使其包含count个元素,并根据需要插入或删除元素。
    • swap(otherList):交换当前列表与otherList之间的内容。
  7. 查找和排序:

    • find(value):返回指向第一个值为value的元素的迭代器;如果找不到,则返回end()。
    • sort():按升序对列表中的元素进行排序。
    • reverse():反转列表中的元素的顺序。

以上只是std::list的一些常见操作,还有很多其他的成员函数可用于更复杂的操作。这里有官方的链接你可以根据具体的需求选择适当的操作。

以下是一些示例,展示了std::list的常见操作:

#include <list>
#include <iostream>int main() {std::list<int> myList;// 插入元素myList.push_back(1);myList.push_front(2);myList.insert(std::next(myList.begin()), 3);// 删除元素myList.pop_back();myList.pop_front();myList.erase(std::next(myList.begin()));// 访问元素std::cout << "Front element: " << myList.front() << std::endl;std::cout << "Back element: " << myList.back() << std::endl;// 迭代器操作for (auto it = myList.begin(); it != myList.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 大小和清空操作std::cout << "Size: " << myList.size() << std::endl;std::cout << "Empty: " << (myList.empty() ? "Yes" : "No") << std::endl;myList.clear();// 查找和排序myList.push_back(5);myList.push_back(2);myList.push_back(4);myList.push_back(1);auto it = myList.find(4);ifit != myList.end()) {std::cout << "Found value 4" << std::endl;}myList.sort();std::cout << "Sorted list: ";for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

三、list与vector的对比

  1. 数据存储方式:

    • vector:使用连续的内存块存储,可以在O(1)时间内访问任意位置的元素。
    • list:使用双向链表存储,每个节点存储一个元素,在O(n)时间内访问任意位置的元素。
  2. 动态性:

    • vector:动态数组,长度可变。能够动态增长和收缩,但在插入和删除操作时可能需要重新分配内存,导致数据的搬移。
    • list:由于使用链表存储,插入和删除操作相对快速,不会涉及内存的重新分配和数据的搬移。
  3. 访问效率:

    • vector:由于数据存储在连续的内存块中,可以通过下标访问元素,提供了O(1)的随机访问效率。
    • list:需要遍历链表才能访问到指定位置的元素,访问效率为O(n)。
  4. 插入和删除操作:

    • vector:在尾部进行插入和删除操作效率高,复杂度为O(1);在中间或头部进行插入和删除操作会导致后续元素的移动,复杂度为O(n)。
    • list:在插入和删除操作时,只需修改相邻节点的指针,复杂度为O(1),对于任意位置的插入和删除都具有较高效率。
  5. 内存使用:

    • vector:由于数据存储在连续的内存块,相对于list可能产生更少的内存开销。
    • list:由于每个元素需要额外的指针进行连接,相对于vector可能产生更多的内存开销。

综上所述,当需要频繁进行随机访问操作或者需要动态增长和收缩容量时,vector是一个更好的选择。而在需要频繁进行插入和删除操作、对访问效率要求不高或者需要避免数据搬移时,list是一个更合适的选择。

温馨提示

感谢您对博主文章的关注与支持!在阅读本篇文章的同时,我们想提醒您留下您宝贵的意见和反馈。如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!

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

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

相关文章

面向对象设计与分析40讲(20)消息驱动编程和事件驱动编程模型

文章目录 消息驱动编程事件驱动编程消息驱动和事件驱动的区别 消息驱动编程 消息驱动是一种编程模型&#xff0c;它基于事件和消息的传递来驱动程序的执行流程。在消息驱动的模型中&#xff0c;系统中的各个组件&#xff08;或对象&#xff09;通过发送和接收消息进行通信和协…

jmeter通过BeanShell对接口参数进行MD5和HmacSHA256加密【杭州多测师_王sir】

一、在eclipse里面编写MD5加密算法 package com.Base64;import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;public class Md5Utils {public static String md5(String sourceStr) {String result "";try {MessageDigest md Mess…

UI设计师的主要职责说明(合集)

UI设计师的主要职责说明1 职责&#xff1a; 1、负责公司移动端、PC端产品相关的交互、UI等设计 2、负责公司宣传册、海报、运营物料、banner等设计 3、负责公司品牌相关的视觉设计 3、制定相关设计规范&#xff0c;提高产品的可用性、不断优化产品体验; 4、与PM、运营紧密…

R语言画图的-- ggplot2(实现图例的精细修改)

文章目录 1. 图的精确修改theme函数实现图的精细修改实现一页多图具体作图中的参数修改(某些特殊的参数)柱状图的参数修改 ggplot2是R中用来作图的很强的包&#xff0c;但是其用法比较大且各种参数比较复杂&#xff0c;我自己使用的时候还经常需要查阅一些关键参数等&#xff0…

UML-A 卷-知识考卷

UML-A 卷-知识考卷 UML有多少种图&#xff0c;请列出每种图的名字&#xff1a; 常用的几种UML图&#xff1a; 类图&#xff08;Class Diagram&#xff09;&#xff1a;类图是描述类、接口、关联关系和继承关系的图形化表示。它展示了系统中各个类之间的静态结构和关系。时序…

项目难点:解决IOS调用起软键盘之后页面样式布局错乱问题

需求背景 &#xff1a; 开发了一个问卷系统重构项目&#xff0c;刚开始开发的为 PC 端&#xff0c;其中最头疼的一点无非就是 IE 浏览器的兼容适配性问题&#xff1b; 再之后项目经理要求开发移动端&#xff0c;简单的说就是写 H5 页面&#xff0c;到时候会内嵌在 App 应用或办…

小研究 - 微服务系统服务依赖发现技术综述(二)

微服务架构得到了广泛的部署与应用, 提升了软件系统开发的效率, 降低了系统更新与维护的成本, 提高了系统的可扩展性. 但微服务变更频繁、异构融合等特点使得微服务故障频发、其故障传播快且影响大, 同时微服务间复杂的调用依赖关系或逻辑依赖关系又使得其故障难以被及时、准确…

【果树农药喷洒机器人】Part6:基于深度相机与分割掩膜的果树冠层体积探测方法

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

如何利用 EMC 模型解决能源服务提供商的瓶颈

01. 什么是合同能源管理&#xff1f; 合同能源管理(EMC-Energy Management Contract) 是一种新型的市场化节能机制,其实质就是以减少的能源费用来支付节能项目全部成本的节能投资方式。&#xff1a;节能服务公司与用能单位以契约形式约定节能项目的节能目标&#xff0c;节能服…

C++ 动态规划经典案例解析之最长公共子序列(LCS)_窥探递归和动态规划的一致性

1. 前言 动态规划处理字符相关案例中&#xff0c;求最长公共子序列以及求最短编辑距离&#xff0c;算是经典中的经典案例。 讲解此类问题的算法在网上一抓应用一大把&#xff0c;即便如此&#xff0c;还是忍不住有写此文的想法。毕竟理解、看懂都不算是真正掌握&#xff0c;唯…

小程序制作教程:从零开始搭建企业小程序

在如今的数字化时代&#xff0c;企业介绍小程序成为了企业展示与推广的重要工具。通过企业介绍小程序&#xff0c;企业可以向用户展示自己的品牌形象、产品服务以及企业文化等内容&#xff0c;进而提高用户对企业的认知度和信任度。本文将介绍如何从零开始搭建一个企业介绍小程…

基于 Nginx All In One 的 Outline Wiki 部署方法

1. Outline 简介 官网&#xff1a;https://www.getoutline.com/ Outline 是一个开源的知识库和团队协作工具&#x1f9e0;&#xff0c;旨在帮助团队共享、组织和协作文档&#x1f4dd;。它提供了一个简洁的界面&#xff0c;使用户能够轻松创建、编辑和查看文档。 以下是 Out…