《21天学通C++》(第十八章)STL list和forward_list

std::list的特点
1.插入和删除操作高效:在任意位置插入或删除元素的开销是 O(1),不需要像 std::vector 那样可能需要移动大量元素。
2.不支持随机访问:访问 std::list 中的元素需要从头开始遍历到所需位置,访问特定元素的时间复杂度为O(n)

1.实例化list

实例化vector时,要指定该动态数组中存储的对象类型

std::list<int> intList;
std::list<float> floatList;

2.在开头和末尾插入元素

使用push_front()push_back()

std::list<int> intList;

    // 在尾部添加元素
    intList.push_back(10);
    intList.push_back(20);

    // 在头部添加元素
    intList.push_front(5);

3.列表初始化

std::list<int> myList = {1, 2, 4, 5};

4.使用insert()在中间插入元素

插入单个元素

void insert(const_iterator position, const value_type& value);
//第一个是插入位置的迭代器,第二个是值
#include <iostream>
#include<list>

int main() {
    std::list<int> myList = {1, 2, 4, 5};

    auto itBegin = myList.begin(); // 获取开始迭代器
    auto itEnd=myList.end();//获取末尾迭代器

    myList.insert(itBegin,0);  // 在开头插入新元素0
    myList.insert(itEnd,6);//在末尾插入新元素6

    std::advance(itBegin,2);//将迭代器移动到第三个元素的位置
    myList.insert(itBegin,55);//在第三个元素之前插入新元素55
    
    for(int num:myList){
        std::cout<<num<<std::endl;
    }
    system("pause");
    return 0;
}

插入多个相同元素

void insert(const_iterator position, size_type count, const value_type& value);
//第一个是插入位置的迭代器,第二个是插入元素的数量,第三个是值
#include <iostream>
#include<list>

int main() {
    std::list<int> myList = {1, 2, 4, 5};

    auto itBegin = myList.begin(); // 获取开始迭代器
    auto itEnd=myList.end();//获取末尾迭代器

    myList.insert(itBegin,3,0);  // 在开头插入3个0
    myList.insert(itEnd,2,6);//在末尾插入2个6

    std::advance(itBegin,2);//将迭代器移动到第三个元素的位置
    myList.insert(itBegin,2,55);//在第三个元素之前插入2个55
    
    for(int num:myList){
        std::cout<<num<<std::endl;
    }
    system("pause");
    return 0;
}

范围插入(例如列表或数组)

template<class InputIt>//需要使用模板函数
void insert(const_iterator position, InputIt first, InputIt last);
//第一个是插入位置的迭代器
//first和last是要插入元素范围的迭代器
#include <iostream>
#include<list>

int main() {
    std::list<int> myList = {1, 2, 4, 5};

    auto itBegin = myList.begin(); // 获取myList开始迭代器
    auto itEnd=myList.end();//获取myList末尾迭代器

    std::list<int> secList={11,22,33};//新的list
   
    myList.insert(itEnd,secList.begin(),secList.end());
    //在myList末尾插入secList

    for(int num:myList){
        std::cout<<num<<std::endl;
    }
    system("pause");
    return 0;
}

5.删除list中的元素

使用erase()

删除单个元素

void erase(const_iterator position);//指向要删除元素的迭代器

删除元素范围

void erase(const_iterator first, const_iterator last);
//first指范围开始的迭代器,last指范围结束的迭代器
#include <iostream>
#include<list>

int main() {
    std::list<int> myList = {1, 2, 3, 4, 5};

    // 删除单个元素
    auto it = myList.begin();//获取开始迭代器
    std::advance(it, 2); // 移动开始迭代器到第三个元素
    myList.erase(it); // 删除第三个元素

    for (const auto& value : myList) {
        std::cout << value << std::endl;
    }

    std::cout<<std::endl;//空一行方便观察
    
    // 删除元素范围
    it = myList.begin();
    std::advance(it, 1);//将开始迭代器移动到第二个元素
    auto itEnd = myList.end();//获取结束迭代器
    std::advance(itEnd, -1); // 移动迭代器到倒数第二个元素
    myList.erase(it, itEnd); // 删除从第二个元素到倒数第二个元素的范围

    // 打印 list 中的所有元素
    for (const auto& value : myList) {
        std::cout << value << std::endl;
    }
    
    system("pause");
    return 0;
}

6.对list中的元素进行反转和排序

①反转使用reverse()函数

#include <iostream>
#include <list>

int main() {
    std::list<int> myList = {1, 2, 3, 4, 5};
    // 反转列表
    myList.reverse();
    // 打印反转后的列表
    std::cout << "Reversed list: ";
    for (int num : myList) {
        std::cout << num << " ";
    }
    system("pause");
    return 0;
}

②排序使用sort()函数

没有参数,默认<运算

list.sort();

使用二元谓词函数作为参数,按照指定标准进行排序

list.sort(Compare);

//Compare可以是以下形式

//1.函数指针
bool Compare(const Type& a, const Type& b);
//2.Lambda表达式
[](const Type& a, const Type& b) -> bool { /* ... */ };
//3.函数对象
struct CompareFunctor {
    bool operator()(const Type& a, const Type& b) const;
};
//4.std::function 对象
std::function<bool(const Type&, const Type&)> Compare;

例子

#include <iostream>
#include <list>

//自定义排序函=函数
bool customCompare(int a, int b) {
    return a > b; // 降序排序
}

int main() {
    std::list<int> myList = {5, 3, 6, 2, 1};

    // 使用默认排序
    myList.sort();
    for (int num : myList) {
        std::cout << num << " ";
    }

    std::cout<<std::endl;//空一行便于观察

    // 使用函数指针进行降序排序
    myList.sort(customCompare);
    for (int num : myList) {
        std::cout << num << " ";
    }

    system("pause");
    return 0;
}

7.对包含对象的list进行排序以及删除其中的元素

如果list的元素类型为类,而不是int等简单内置类型,又要对其包含类的属性进行排序。

①假设我们有一个简单的 Person 类,我们想根据人的年龄进行降序排序:

#include <iostream>
#include <list>

//定义一个Person类
struct Person {
    std::string name;
    int age;
    
    Person(const std::string& name, int age) : name(name), age(age) {}//初始化
};

//自定义年龄比较函数
bool compareByAge(const Person& a, const Person& b) {
    return a.age > b.age; // 降序排序
}

int main() {

	//创建一个人的list,包含名字和年龄
    std::list<Person> peopleList = {
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35}
    };

    // 使用函数指针按年龄降序排序
    peopleList.sort(compareByAge);

    // 打印排序后的列表
    for (const auto& person : peopleList) {
        std::cout << person.name << " - " << person.age << std::endl;
    }
    system("pause");
    return 0;
}

②可以使用std::list::remove来删除满足条件的元素

#include <iostream>
#include <list>

//定义Person类
struct Person {
    std::string name;
    int age;

    //初始化
    Person(const std::string& name, int age) : name(name), age(age) {}
};

//自定义删除函数
bool IsOlderThan30(const Person& person) {
    return person.age > 30;
}

int main() {

    //创建一个人的list,包含名字和年龄
    std::list<Person> peopleList = {
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35},
        {"Jonh", 21}

    };

    // 删除年龄大于30的
    peopleList.remove_if(IsOlderThan30);

    // 打印排序后的列表
    for (const auto& person : peopleList) {
        std::cout << person.name << " - " << person.age << std::endl;
    }
    system("pause");
    return 0;
}

8.C++11引入的std::forward_list

要使用它,需要添加头文件<forward_list>,用法和list很像,但由于是一种单向链表,所以只能沿一个方向移动迭代器,所以插入只能使用push_front(),基本操作如下:

#include <iostream>
#include <forward_list>

int main() {
    std::forward_list<int> flist = {1, 2, 3, 4, 5};

    // 在头部插入一个新元素
    flist.push_front(0);

    // 删除头部元素
    flist.pop_front();

    // 遍历 forward_list 并打印每个元素
    for (int num : flist) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    system("pause");
    return 0;
}

引入std::forward_list 设计旨在解决一些 std::list(双向链表)的局限性,并提供一些特定的性能优势

  1. 性能优化:std::list 中,每个元素都需要存储两个指针(指向前一个和后一个元素),而 std::forward_list 中的每个元素只需要存储一个指向下一个元素的指针。这减少了内存的使用,并且可能提高缓存局部性,从而提升性能。
  2. 头部和尾部操作的效率: std::forward_list 提供了与 std::list 相似的高效头部和尾部插入与删除操作,但因为只维护单向链接,可能在某些实现中提供更优的性能。
  3. 编译器优化: 单向链表的结构可能使得编译器更容易进行某些优化,尤其是在内存对齐和迭代器实现方面。

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

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

相关文章

Junit 测试中如何对异常进行断言

本文对在 Junit 测试中如何对异常进行断言的几种方法进行说明。 使用 Junit 5 如果你使用 Junit 5 的话,你可以直接使用 assertThrows 方法来对异常进行断言。 代码如下: Exception exception = assertThrows(NumberFormatException.class, () -> {new Integer("on…

fiscobcos 3.x linux安装与java简单调用

所用环境 vmware 16 Pro centos7.6 jdk11.0.6 ideal 2022 1、安装fiscobcos # 创建操作目录 # cd ~ && mkdir -p fisco && cd fisco# 下载建链脚本 # curl -#LO https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v3.6.0/build_chain.sh &a…

Spring Security + JWT 实现登录认证和权限控制

Spring Security JWT 实现登录认证和权限控制 准备步骤 准备好一些常用的工具类&#xff0c;比如jwtUtil&#xff0c;redisUtil等。引入数据库&#xff0c;mybatis等&#xff0c;配置好controller&#xff0c;service&#xff0c;mapper&#xff0c;保证能够正常的数据请求。…

【python】条件语句与循环语句

目录 一.条件语句 1.定义 2.条件语句格式 &#xff08;1&#xff09;if &#xff08;2&#xff09;if-else &#xff08;3&#xff09;elif功能 &#xff08;4&#xff09;if嵌套使用 3.猜拳游戏 二.循环语句 1. while循环 2.while嵌套 3.for循环 4.break和conti…

k8s部署skywalking(helm)

官方文档 官方文档说明&#xff1a;Backend setup | Apache SkyWalking官方helm源码&#xff1a;apache/skywalking-helm官方下载&#xff08;包括agent、apm&#xff09;:Downloads | Apache SkyWalking 部署 根据官方helm提示&#xff0c;选择你自己部署的方式&#xff0c…

PyTorch深度学习框架:从入门到实战

前言 学习 PyTorch 深度学习框架之前先学会深度学习和卷积神经网络 CNN &#xff0c;这样学习起来会更香嗷。 Windows系统下PyTorch的环境配置 Anaconda是什么&#xff1a; Anaconda是一个开源的Python发行版本&#xff0c;专注于数据分析领域。它包含了conda、Python等190多…

解决python/pycharm中import导入模块时报红却能运行的问题

一、问题 导入时报红&#xff0c;如下 二、解决 右键单击项目&#xff0c;将项目Mark Directory as→Sources Root 三、效果 报红消失 学习导航&#xff1a;http://www.xqnav.top

Docker网络基础

简介 Docker 本身的技术依赖于近年来 Linux 内核虚拟化技术的发展,Docker 对 Linux 内核的特性有很强的依赖。Docker 使用到的与 Linux 网络有关的主要技术有:网络命名空间、veth 设备对、网桥、ipatables 、路由。 网络命名空间 为了支持网络协议栈的多个实例,Linux在网络栈…

使用Docker安装Jenkins

大家好&#xff0c;今天给大家分享如何使用docker安装jenkins&#xff0c;关于docker的安装和常用命令可以参考下面两篇文章&#xff0c;使用docker可以提高资源利用率&#xff0c;能够在不同的环境中轻松迁移和部署应用&#xff0c;在本文中就不过多赘述了。 Docker常用命令 …

大数据BI可视化(Echarts组件)项目开发-熟悉动画使用功能4.0

加载动画 数据源 [{ "gender": "female", "height": 161.2, "weight": 51.6 }, { "gender": "female", "height": 167.5, "weight": 59 }, { "gender": "female", &quo…

opencv基础篇 ——(十六)图形绘制与填充

OpenCV 提供了丰富的图形绘制和填充功能&#xff0c;主要通过 cv::rectangle, cv::circle, cv::line, cv::polylines, cv::fillPoly 和 cv::ellipse 等函数实现。以下是一些基本的图形绘制和填充操作的说明&#xff1a; 矩形: 函数: cv::rectangle语法: cv::rectangle(img, rec…

一文2500字Robot Framework自动化测试框架超强教程

1、Robot Framework简介 Robot Framework是一个基于Python的可扩展关键字驱动的自动化框架&#xff0c;用于验收测试&#xff0c;验收测试驱动开发&#xff08;ATDD&#xff09;&#xff0c;行为驱动开发&#xff08;BDD&#xff09;和机器人流程自动化&#xff08;RPA&#xf…

SqlException 口令已经失效

Orcle密码过期了 //查看过期时间 SELECT * FROM dba_profiles s WHERE s.profileDEFAULT AND resource_namePASSWORD_LIFE_TIME;//修改过期时间 alter PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;

Debian是什么?有哪些常用命令

目录 一、Debian是什么&#xff1f; 二、Debian常用命令 三、Debian和CentOS的区别 四、Debian和CentOS的优缺点 五、Debian和CentOS的运用场景 一、Debian是什么&#xff1f; Debian是一种流行的开源Linux操作系统。 Debian是一个以Linux内核为基础的操…

轻松上手的LangChain学习说明书

一、Langchain是什么&#xff1f; 如今各类AI模型层出不穷&#xff0c;百花齐放&#xff0c;大佬们开发的速度永远遥遥领先于学习者的学习速度。。为了解放生产力&#xff0c;不让应用层开发人员受限于各语言模型的生产部署中…LangChain横空出世界。 Langchain可以说是现阶段…

强化学习:时序差分法【Temporal Difference Methods】

强化学习笔记 主要基于b站西湖大学赵世钰老师的【强化学习的数学原理】课程&#xff0c;个人觉得赵老师的课件深入浅出&#xff0c;很适合入门. 第一章 强化学习基本概念 第二章 贝尔曼方程 第三章 贝尔曼最优方程 第四章 值迭代和策略迭代 第五章 强化学习实例分析:GridWorld…

硬盘遭遇误删分区?这些恢复技巧你必须掌握!

在日常使用电脑的过程中&#xff0c;我们有时会遇到一些棘手的问题&#xff0c;其中误删分区无疑是一个令人头疼的难题。误删分区意味着我们不小心删除了硬盘上的某个分区&#xff0c;导致该分区内的所有数据瞬间消失。对于许多用户来说&#xff0c;这可能会引发极大的恐慌和焦…

模拟电路设计与分析

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 计算机工作原理存储单元 计算机工作原理 计算机最底层语言是二进制&#xff0c;和我们生活中使用的阿拉伯数字是十进制数&#x…

【算法】滑动窗口——长度最小的子数组

本篇文章是用一个实例来介绍常用算法之一“滑动窗口”的相关概念&#xff0c;有需要借鉴即可。 目录 1.题目2.暴力求解2.1暴力求解思路&#xff1a;2.2时间复杂度是多少&#xff1f; 3.暴力求解的优化3.1固定left的情况下&#xff0c;优化right的次数。3.2sum求值优化3.3不同组…

2.5W字 一文读懂汽车智能座舱的FLASH 存储市场、技术

吃瓜群众&#xff1a;机哥&#xff0c;存储是什么玩意&#xff0c;我买手机、电脑的时候导购员都说买内存大的&#xff0c;三星的好&#xff0c;品牌大&#xff0c;问题少&#xff0c;我也只有看哪个内存大就买那个。 机哥&#xff1a;额&#xff0c;这个嘛&#xff0c;说来话长…