09.list 容器

news2025/1/21 0:49:48

9、list 容器

功能:

  • 将数据进行链式存储

链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的

链表的组成:

  • 链表由一系列结点组成

结点的组成:

  • 一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

STL中的链表是一个双向循环链表

1694782885909

由于链表的存储方式并不是连续的内存空间,因此链表 list 中的迭代器只支持前移和后移,属于双向迭代器

list 的优点:

  • 采用动态存储分配,不会造成内存浪费和溢出
  • 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素

list 的缺点:

  • 链表灵活,但是空间(指针域) 和 时间(遍历)额外耗费较大

List 有一个重要的性质,插入操作和删除操作都不会造成原有 list 迭代器的失效,这在 vector 是不成立的。

9.1 list 构造函数

功能描述:

  • 创建 list 容器

函数原型:

list<T> lst;   			// list 采用采用模板类实现,对象的默认构造形式:
list(beg,end); 			// 构造函数将 [beg, end) 区间中的元素拷贝给本身。
list(n,elem);  			// 构造函数将 n 个 elem 拷贝给本身。
list(const list &lst); 	// 拷贝构造函数。
#include <iostream>
#include <list>

using namespace std;

void printList(const list<int>& L) {
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);

    list<int>L2(L1.begin(), L1.end());
    printList(L2);

    list<int>L3(L2);
    printList(L3);

    list<int>L4(10, 1000);
    printList(L4);
}

int main() {
    test01();
    system("pause");
    return 0;
}

9.2 list 赋值和交换

功能描述:

  • 给 list 容器进行赋值,以及交换 list 容器

函数原型:

assign(beg, end); 					// 将 [beg, end) 区间中的数据拷贝赋值给本身。
assign(n, elem);  					// 将 n 个 elem 拷贝赋值给本身。
list& operator=(const list &lst); 	// 重载等号操作符
swap(lst); 							//将 lst 与本身的元素互换。
#include <iostream>
#include <list>
using namespace std;

void printList(const list<int>& L) {
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
// 赋值和交换
void test01() {
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);
    // 赋值
    list<int>L2;
    L2 = L1;
    printList(L2);

    list<int>L3;
    L3.assign(L2.begin(), L2.end());
    printList(L3);

    list<int>L4;
    L4.assign(10, 100);
    printList(L4);
}

// 交换
void test02() {
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    list<int>L2;
    L2.assign(10, 100);
    cout << "交换前: " << endl;
    printList(L1);
    printList(L2);
    cout << endl;
    L1.swap(L2);
    cout << "交换后: " << endl;
    printList(L1);
    printList(L2);
}

int main() {
    //test01();
    test02();
    system("pause");
    return 0;
}

9.3 list 大小操作

功能描述:

  • 对 list 容器的大小进行操作

函数原型:

size(); 	// 返回容器中元素的个数
empty(); 	// 判断容器是否为空

// 重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。
// 如果容器变短,则末尾超出容器长度的元素被删除。
resize(num); 

// 重新指定容器的长度为 num,若容器变长,则以 elem 值填充新位置。
// 如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem); 
#include <iostream>
#include <list>
using namespace std;

void printList(const list<int>& L) {
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
// 大小操作
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    if (L1.empty())
    {
        cout << "L1为空" << endl;
    }
    else
    {
        cout << "L1不为空" << endl;
        cout << "L1的大小为: " << L1.size() << endl;
    }
    // 重新指定大小
    L1.resize(10);
    printList(L1);
    L1.resize(2);
    printList(L1);
}
int main() {
    test01();
    system("pause");
    return 0;
}

总结:

  • 判断是否为空 — empty
  • 返回元素个数 — size
  • 重新指定个数 — resize

9.4 list 插入和删除

功能描述:

  • 对 list 容器进行数据的插入和删除

函数原型:

push_back(elem);		// 在容器尾部加入一个元素
pop_back();     		// 删除容器中最后一个元素
push_front(elem);		// 在容器开头插入一个元素
pop_front();    		// 从容器开头移除第一个元素
insert(pos,elem);		// 在 pos 位置插 elem 元素的拷贝,返回新数据的位置。
insert(pos,n,elem);		// 在 pos 位置插入 n 个 elem 数据,无返回值。
insert(pos,beg,end);	// 在 pos 位置插入 [beg,end) 区间的数据,无返回值。
clear();        		// 移除容器的所有数据
erase(beg,end); 		// 删除 [beg,end) 区间的数据,返回下一个数据的位置。
erase(pos);     		// 删除 pos 位置的数据,返回下一个数据的位置。
remove(elem);   		// 删除容器中所有与 elem 值匹配的元素。
#include <iostream>
#include <list>
using namespace std;

void printList(const list<int>& L) {
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
// 插入和删除
void test01() {
    list<int> L;
    // 尾插
    L.push_back(10);
    L.push_back(20);
    L.push_back(30);
    // 头插
    L.push_front(100);
    L.push_front(200);
    L.push_front(300);
    printList(L);

    // 尾删
    L.pop_back();
    printList(L);
    // 头删
    L.pop_front();
    printList(L);

    // 插入
    list<int>::iterator it = L.begin();
    L.insert(++it, 1000);
    printList(L);
    // 删除
    it = L.begin();
    L.erase(++it);
    printList(L);
    // 移除
    L.push_back(10000);
    L.push_back(10000);
    L.push_back(10000);
    printList(L);
    L.remove(10000);
    printList(L);

    // 清空
    L.clear();
    printList(L);
}
int main() {
    test01();
    system("pause");
    return 0;
}

总结:

  • 尾插 — push_back
  • 尾删 — pop_back
  • 头插 — push_front
  • 头删 — pop_front
  • 插入 — insert
  • 删除 — erase
  • 移除 — remove
  • 清空 — clear

9.5 list 数据存取

功能描述:

  • 对 list 容器中数据进行存取

函数原型:

front(); 			// 返回第一个元素。
back(); 			// 返回最后一个元素。
#include <iostream>
#include <list>
using namespace std;
//数据存取
void test01() {
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    //cout << L1.at(0) << endl;	// 错误:不支持 at 访问数据
    //cout << L1[0] << endl; 	// 错误:不支持 [] 方式访问数据
    cout << "第一个元素为:" << L1.front() << endl;
    cout << "最后一个元素为:" << L1.back() << endl;

    // list容器的迭代器是双向迭代器,不支持随机访问
    list<int>::iterator it = L1.begin();
    //it = it + 1; 				// 错误:不可以跳跃访问,即使是+1
}

int main() {
    test01();
    system("pause");
    return 0;
}

总结:

  • list 容器中不可以通过 [] 或者 at 方式访问数据
  • 返回第一个元素 — front
  • 返回最后一个元素 — back

9.6 list 反转和排序

功能描述:

  • 将容器中的元素反转,以及将容器中的数据进行排序

函数原型:

reverse(); 			// 反转链表
sort(); 			// 链表排序
#include <iostream>
#include <list>
using namespace std;

void printList(const list<int>& L) {
    for (list<int>::const_iterator it = L.begin(); it != L.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
}

bool myCompare(int val1, int val2) {
    return val1 > val2;
}

// 反转和排序
void test01() {
    list<int> L;
    L.push_back(90);
    L.push_back(30);
    L.push_back(20);
    L.push_back(70);
    printList(L);
    // 反转容器的元素
    L.reverse();
    printList(L);

    // 排序
    L.sort();
    printList(L);
    L.sort(myCompare);
    printList(L);
}
int main() {
    test01();
    system("pause");
    return 0;
}

总结:

  • 反转 — reverse
  • 排序 — sort (成员函数)

9.7 排序案例

案例描述:

  • 将 Person 自定义数据类型进行排序,Person 中属性有姓名、年龄、身高

排序规则:

  • 按照年龄进行升序,如果年龄相同按照身高进行降序
#include <iostream>
#include <list>
using namespace std;

class Person {
public:
    Person(string name, int age, int height) {
        this->m_name = name;
        this->m_age = age;
        this->m_height = height;
    }
public:
    string m_name;
    int m_age;
    int m_height;
};

bool Compareperson(Person& p1, Person& p2) {
    if (p1.m_age == p2.m_age) {
        return p1.m_height > p2.m_height;
    }
    else {
        return p1.m_age < p2.m_age;
    }
}

void test01() {
    list<Person> L;
    Person p1("刘备",35,175);
    Person p2("曹操", 45, 180);
    Person p3("马超", 25, 190);
    Person p4("赵云", 35, 180);
    Person p5("张飞", 30, 200);

    L.push_back(p1);
    L.push_back(p2);
    L.push_back(p3);
    L.push_back(p4);
    L.push_back(p5);

    for (list<Person>::iterator it = L.begin(); it != L.end(); ++it) {
        cout << "姓名:" << it->m_name << " 年龄:" << (*it).m_age << " 身高:" << (*it).m_height << endl;
    }
    cout << "---------------------------" << endl;
    L.sort(Compareperson);
    for (list<Person>::iterator it = L.begin(); it != L.end(); ++it) {
        cout << "姓名:" << it->m_name << " 年龄:" << it->m_age << " 身高:" << it->m_height << endl;
    }
}

int main() {
    test01();
    system("pause");
    return 0;
}

总结:

  • 对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序
  • 高级排序只是在排序规则上在进行一次逻辑规则指定,并不复杂

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

携手河南恩坤德,共创养殖新篇章

在这个充满机遇与挑战的时代&#xff0c;养殖业正在经历一场前所未有的变革。作为养殖户&#xff0c;您需要一个能够与您共同应对变革、共创未来的合作伙伴。河南恩坤德农业正是这样一个值得信赖的伙伴&#xff0c;我们携手共创养殖新篇章。 河南恩坤德农业以客户需求为导向&am…

SOLIDWORKS Plastics基础功能详解(一)

Batch Manager Batch Manager PropertyManager 经过重新设计&#xff0c;提高了可用性。 在各部分中重新排列用户界面元素为 Batch Manager 提供了一个简化的工作流程。能够指定分析任务的最大 CPU 数。改进了分配给分析任务的模拟类型以及添加、运行和暂停分析任务的控件的可…

Python数据科学视频讲解:特征归一化、特征标准化、样本归一化

5.1 特征归一化、特征标准化、样本归一化 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解5.1节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#…

nodejs+vue+ElementUi资源互助共享平台的设计

后台&#xff1a;管理员功能有个人中心&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;咨询师管理&#xff0c;萌宝信息管理&#xff0c;幼儿知识管理&#xff0c;保姆推荐管理&#xff0c;音频资源管理&#xff0c;二手商品管理&#xff0c;商品分类管理&#xff0c;资…

实战经验分享:开发同城外卖跑腿小程序

下文&#xff0c;小编将与大家一同探究同城外卖跑腿小程序的开发实战&#xff0c;包括但不限于技术选型、开发流程、用户体验等多个方面。 1.技术选型 在同城外卖跑腿小程序的开发中&#xff0c;技术选型是至关重要的一环。对于前端&#xff0c;选择了使用Vue.js框架&#xff…

Qml之自定义Button

Qml之自定义Button 前言一、图标Button二、字体Button1.重写Background和ContentItem2.采用ButtonStyle前言 提示: 自定义Button控件如何分为带图片的Iconbutton和原生控件重写的Button。最终效果如下: 提示:以下是本篇文章正文内容,下面案例可供参考 一、图标Button im…

DETR 【目标检测里程碑的任务】

paper with code - DETR 标题 End-to-End Object Detection with Transformers end-to-end 意味着去掉了NMS的操作&#xff08;生成很多的预测框&#xff0c;nms 去掉冗余的预测框&#xff09;。因为有了NMS &#xff0c;所以调参&#xff0c;训练都会多了一道工序&#xff0c…

【Linux基础开发工具】gcc/g++使用make/Makefile

目录 前言 gcc/g的使用 1. 语言的发展 1.1 语言和编译器自举的过程 1.2 程序翻译的过程&#xff1a; 2. 动静态库的理解 Linux项目自动化构建工具-make/makefile 1. 快速上手使用 2. makefile/make执行顺序的理解 前言 了解完vim编辑器的使用&#xff0c;接下来就可以尝…

解决Unity物体速度过快无法进行碰撞检测(碰撞检测穿透)

解决Unity物体速度过快无法进行碰撞检测&#xff08;碰撞检测穿透&#xff09; 一、解决碰撞检测穿透方法一Collision Detection碰撞检测总结&#xff1a; 二、解决碰撞检测穿透方法二 一、解决碰撞检测穿透方法一 首先我们知道只要是跟碰撞相关的基本都是离不开刚体 Rigidbod…

海康威视运行管理中心 Fastjson RCE

漏洞描述 海康威视运行管理中心系统存在低版本Fastjson远程命令执行漏洞&#xff0c;攻击者可在未鉴权情况下获取服务器权限&#xff0c;且由于存在相关依赖&#xff0c;即使服务器不出网无法远程加载恶意类也可通过本地利用链直接命令执行&#xff0c;从而获取服务器权限。 漏…

nodejs+vue+ElementUi会员制停车场车位系统

总之&#xff0c;智能停车系统使停车场管理工作规范化&#xff0c;系统化&#xff0c;程序化&#xff0c;避免停车场管理的随意性&#xff0c;提高信息处理的速度和准确性&#xff0c;能够及时、准确、有效的查询和修改停车场情况。 三、任务&#xff1a;小组任务和个人任务 智…

vue3 登录页和路由表开发

目录 应用场景/背景描述&#xff1a; 开发流程&#xff1a; 详细开发流程&#xff1a; 总结/分析&#xff1a; 背景描述 在上一篇的基础上开始开发&#xff0c;element-plusvue3 上一篇说道详细迁移的过程&#xff0c;如下&#xff1a; 所以我这篇开始了第一步&#xff0c…

Shell编程从入门到实战

Shell 概述 &#xff08;1&#xff09;Linux 提供的 Shell 解析器有 [rootflinkTenxun ~]# cat /etc/shells&#xff08;2&#xff09;bash 和 sh 的关系 [rootflinkTenxun bin]# ll | grep bash&#xff08;3&#xff09;Centos 默认的解析器是 bash [rootflinkTenxun bin]…

从Maven初级到高级

一.Maven简介 Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。 一个 Maven 工程有约定的目录结构&#xff0c;约定的目录结构对于 Maven 实现自动化构建而言是必不可少的一环&#xff0c;就拿自动编译来说&#xff0c;Maven 必须 能…

安装nodejs,配置环境变量并将npm设置淘宝镜像源

安装nodejs并将npm设置淘宝镜像源 1. 下载nodejs 个人不喜欢安装包&#xff0c;所以是下载zip包的方式。这里我下载的node 14解压包版本 下载地址如下&#xff1a;https://nodejs.org/dist/v14.15.1/node-v14.15.1-win-x64.zip 想要其他版本的小伙伴去https://nodejs.org/di…

【C++】bind绑定包装器全解(代码演示,例题演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Linux》…

7ADC模数转换器

一.模数转换原理 ADC模拟-数字转换器可以将引脚上连续变化的模拟电压转换成内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁。另外一种是DAC既是与前面相反&#xff0c;如PWM波&#xff0c;由于PWM电路简单且没有额外的功率损耗&#xff0c;更适用于惯性系统的…

HarmonyOS4.0系统性深入开发02 UIAbility组件详解(上)

UIAbility组件概述 概述 UIAbility组件是一种包含UI界面的应用组件&#xff0c;主要用于和用户交互。 UIAbility组件是系统调度的基本单元&#xff0c;为应用提供绘制界面的窗口&#xff1b;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例…

基于Java SSM框架实现列车火车高铁票务信息管理系统项目【项目源码+论文说明】

基于java的SSM框架实现列车火车高铁票务信息管理系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被…

Linux学习笔记8-Uboot移植-网络设置和其他坑的解决

Linux之所以被称为操作系统&#xff0c;肯定是需要有引导程序来启动各个关键外设的运行&#xff0c;这里可以和个人电脑PC做个类比。我们在开机的时候是不是先要进入BIOS&#xff0c;BIOS在初始化硬盘、内存、USB接口、网口等之后&#xff0c;才可以进入Windows系统对吧&#x…