【C++第三阶段】list容器排序

以下内容仅为当前认识,可能有不足之处,欢迎讨论!


文章目录

  • 构造函数
  • 赋值和交换
  • 大小操作
  • 插入和删除
  • 数据存取
  • 反转和排序
  • 排序案例


image-20240411211821277

list容器在STL中是双向循环链表。

如图所示,每一个节点三个域,前向指针域,后向指针域,数据域。前向指针域指向前一个结点的地址,后向指针域指向后一个结点的地址,数据与存放该结点数据。第一个结点的前向指针指向最后一个结点的地址;最后一个结点的后向指针指向第一个结点的地址。

但是值得注意的是,插入删除操作不会造成list迭代器的失效,而迭代器在vector中是一次性的。

list优点:

采用动态存储分配,不会造成内存浪费和溢出。

链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素。

list缺点:

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

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

总结:STL中list和vector是两个最常使用的容器,各有优缺点。

构造函数

目的函数
默认构造形式list<T> lst;
将[beg,end)区间中的元素拷贝给本身list(beg,end);
构造函数将n个elem拷贝给本身list(n,elem);
拷贝构造函数list(const list &lst);

示例代码:

void test0419a() {list<int> lst;lst.push_back(10);lst.push_back(20);lst.push_back(30);lst.push_back(40);print(lst);cout << "区间元素拷贝给本身" << endl;list<int> lst2(++lst.begin(), lst.end());print(lst2);cout << "构造函数将n个elem拷贝给本身" << endl;list<int> lst3(3, 6);print(lst3);cout << "拷贝构造函数" << endl;list<int> lst4 = lst2;print(lst4);
}

运行结果:

image-20240428205708289

赋值和交换

赋值和交换,说的是list容器中,给list容器进行赋值,以及交换list容器。

目的函数原型
将区间内的数据赋值给本身assign(begin,end);
将n个elem拷贝赋值给本身assign(n,elem);
重载等号操作符list& operator=(const list &lst);
将lst与本身的元素互换swap(lst);

示例代码:

void test0428a() {list<int> lst;for (int i = 10; i < 14; i++) {lst.push_back(i*2/3+1);lst.push_front(i * 3 / 2-1);}cout << "lst为↓" << endl;print(lst);list<int> lst2;lst2.assign(lst.begin(), lst.end());cout << "lst2为↓" << endl;print(lst2);list<int> lst3;lst3 = lst;cout << "lst3为↓" << endl;print(lst3);list<int> lst4;cout << "lst4为↓" << endl;lst4.assign(10, 100);print(lst4);swap(lst3, lst4);cout << "lst3为↓" << endl;print(lst3);cout << "lst4为↓" << endl;print(lst4);}

运行结果:

image-20240428211919091

大小操作

目的:对容器的大小进行操作

目的函数
返回容器中元素个数size()
判断容器是否为空empty()
重新制定容器长度,后长度若长于原长度,则以默认值填充,后长度若短于原长度,则截断。resize(num)
以指定值填充。resize(num,elem)

示例代码:

void test0429a() {list<int> lst;for (int i = 1; i < 4; i++) {lst.push_back(i * 2 - 3);lst.push_front(i * 3 - 2);}cout << "lst当前为:";print(lst);cout << "lst的元素个数:" << lst.size() << "." << endl;cout << "lst是空list容器吗?" << endl;if (lst.empty()) {cout << "lst是空容器。" << endl;}else {cout << "lst不是空容器。" << endl;}cout << "重新lst裁剪大小为4个" << endl;lst.resize(4);print(lst);cout << "扩充lst为7个,以7填充。" << endl;lst.resize(7, 7);print(lst);
}

运行结果:

image-20240429094748862

插入和删除

目的:对list容器进行数据的插入和删除。

目的函数
容器尾部添加一个元素push_back(elem)
删除容器最后一个元素pop_back()
容器开头添加一个元素push_front(elem)
删除容器最后一个元素pop_front()
在pos位置插入elem元素的拷贝,返回新数据的位置insert(pos,elem)
在pos位置插入n个elem数据, 不需要返回值insert(pos,n,elem)
在pos位置插入[begin,end)区间的数据,没有返回值insert(pos,begin,end)
删除容器中所有数据clear()
删除[begin,end)区间的数据,返回下一个数据的位置。erase(begin,end)
删除pos位置的数据,返回下一个数据的位置erase(pos)
删除容器中所有值为elem的元素remove(elem)

示例代码:

void test0429b() {list<int> lst;list<int> tsl;for (int i = 0; i < 4; i++) {lst.push_back(i * 2 - 5);lst.push_front(i * 5 - 2);tsl.push_back(i);}cout << "lst当前为↓" << endl;print(lst);cout << "删除lst头部第一个元素后,lst↓" << endl;lst.pop_front();print(lst);cout << "删除lst尾部最后一个元素后,lst↓" << endl;lst.pop_back();print(lst);list<int> ::iterator begin = lst.begin();cout << "在第2个位置插入1个3" << endl;lst.insert(++begin, 3);print(lst);cout << "在第3个位置插入4个2" << endl;lst.insert(++begin, 4, 2);print(lst);cout << "lst当前为↓" << endl;print(lst);cout << "tsl当前为↓" << endl;print(tsl);cout << "lst尾部插入tsl后,lst为↓" << endl;lst.insert(lst.end(), tsl.begin(), tsl.end());print(lst);cout << "lst删除第一个元素的位置,返回下一个数据的位置为" << endl;lst.erase(lst.begin());print(lst);cout << "此时begin的位置对应的元素是" << *begin << endl;cout << "lst删除第begin+1个到最后一个元素的数据后,为↓" << endl;lst.erase(++begin, lst.end());print(lst);}

运行结果:

image-20240429102550302

数据存取

目的:对list容器中数据进行存取

目的函数
返回第一个元素值front()
返回最后一个元素值back()

示例代码:

void test0429c() {list<int> lst;for (int i = -2; i < 3; i++) {lst.push_back(i * 2 - 2);}print(lst);cout << "第一个元素值为:" << lst.front() << endl;cout << "最后一个元素值为:" << lst.back() << endl;}

运行结果:

image-20240429103149556

list不可以用[]访问容器中的元素,也不可以用at()方式访问容器中的元素。

因为list是链表,不是用连续线性空间存储数据,迭代器也是不支持随机访问的。

反转和排序

目的:①反转list容器内元素;②对list容器进行排序。

反转可以直接用容器内方法,排序

所有不支持随机访问迭代器的容器,不可以用标准算法。

所以,要想对这些容器进行排序,可以使用内部提供的对应算法。

排序默认是升序,如果是降序,则需要写一个对应函数。

示例代码:

void test0429d() {list<int> lst;for (int i = -2; i < 3; i++) {lst.push_back(i * 2 - 2);lst.push_front(i * i - 2);}cout << "now lst -->"<<endl;print(lst);cout << endl;cout << "after reverse,the lst ==" << endl;lst.reverse();print(lst);cout << endl;cout << "after sort ,lst == " << endl;lst.sort();print(lst);cout << endl;cout << "now sort by function compare , lst == " << endl;lst.sort(compare<int>);print(lst);cout << endl;
}

运行结果:

image-20240429105248422

排序案例

案例描述:将person自定义数据类型排序,属性有姓名,年龄,身高。

规则:按照年龄进行升序(默认),如果年龄相同,则按照身高进行降序。

疑问:怎么通过某一个属性进行排序?

看视频解决:通过自定义的排序函数。

示例代码:

#include<iostream>#include<string>using namespace std;#include<list>template<typename T>
void print(list<T>& lst) {for (typename list<T>::iterator lst_front = lst.begin(); lst_front != lst.end(); ++lst_front) {cout << *lst_front;//cout << "  ";}cout << endl;
}class Person {
public:Person() {};Person(string name, int age, double height) :person_name(name), person_age(age), person_height(height) {};
public:string person_name;int person_age;double person_height;
};ostream& operator<<(ostream& out, Person& person) {cout << person.person_name << "年龄为:" << person.person_age << ",\t身高为:" << person.person_height << "." << endl;//在实现operator<<时,最好不要直接使用cout,而应该使用传递给函数的ostream对象out,这可以提高代码的可复用性。——GPT4return out;
}//template <typename Person>
bool person_compare(const Person& per, const Person& son) {if (per.person_age == son.person_age) {return per.person_height > son.person_height;}return son.person_age > per.person_age;
}void test0429e() {Person person[5];Person One("大道", 20, 1.85);person[0] = One;Person Two("两极", 19, 1.83);person[1] = Two;Person Three("三眼", 22, 1.84);person[2] = Three;Person Four("四象", 22, 1.86);person[3] = Four;Person Five("五行", 24, 1.88);person[4] = Five;list<Person> lst_ps;for (int i = 0; i < (sizeof(person) / sizeof(person[0])); i++) {lst_ps.push_back(person[i]);}cout << "Person 排序前" << endl;print(lst_ps);cout << "Person 排序后" << endl;lst_ps.sort(person_compare);print(lst_ps);}int main() {test0429e();system("pause");return 0;
}

运行结果:

image-20240429115426985


以上是我的学习笔记,希望对你有所帮助!
如有不当之处欢迎指出!谢谢!

学吧,学无止境,太深了

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

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

相关文章

用户中心(上)

文章目录 企业做项目流程需求分析技术选型计划初始化项目数据库设计登录/注册⽤户管理&#xff08;仅管理员可⻅&#xff09; 初始化项目⼀、前端初始化1.下载nodejs2.Ant Design Pro相关问题1.前端项目启动时报错、无法启动&#xff1f;2.如何初始化前端项目&#xff1f;为什么…

vue 模板字符串

1.模板字符串换行问题 white-space: pre-wrap; 2. 鼠标移入 显示提示框 点击手动隐藏 myChart.on("mouseover", function (params) {myChart.dispatchAction({type: "downplay",}); }); tooltip: {show: true, //是否显示提示框组件&#xff0c;包括…

机器人实验室CNRS-AIST JRL, IRL介绍

一、背景 作为搞机器人方向的学生&#xff0c;必须时常关注国际上顶尖实验室的研究成果&#xff0c;以免自己做的方向out&#xff0c;除了大家耳熟能详的Boston Dynamics&#xff0c;还有许多非常厉害的机器人实验室值得我们关注&#xff0c;如日本的CNRS-AIST JRL, IRL实验室…

spring cache(一)介绍

一、介绍 1、背景 项目中使用最多的缓存技术就是Redis,用Redis就可以实现了&#xff0c;为什么需要使用spring cache&#xff1f; 先看下我们使用缓存步骤: &#xff08;1&#xff09;查寻缓存中是否存在数据&#xff0c;如果存在则直接返回结果 &#xff08;2&#xff09…

虚函数表与虚函数表指针

虚函数表与虚函数表是用来实现多态的&#xff0c;每一个类只有一个虚函数表 静态多态&#xff1a;函数重载&#xff08;编译期确定&#xff09; 动态多态&#xff1a;虚函数&#xff08;运行期确定&#xff09; 虚函数表的创建时机&#xff1a; 生成时间&#xff1a; 编译期…

生活服务推出品牌实惠团购,覆盖五一假期“吃喝玩乐”多场景

4月26日&#xff0c;抖音生活服务平台上线“跟着大牌过五一”活动会场&#xff0c;携手22家连锁品牌商家&#xff0c;于“五一”前推出优价团购和时令新品&#xff0c;覆盖“吃喝玩乐”多重购物需求&#xff0c;助力假期消费。同时&#xff0c;伴随各地涌现的文旅热潮&#xff…

SAP-ABAP-创建数据元素-02

事物码&#xff1a;SE11 三种数据对象&#xff0c;此处选择‘数据元素’ 基本类型&#xff1a;可以使用预定义或者域&#xff0c;下面一预定义为例&#xff0c;维护数据类型CHAR和长度10 点击字段标签&#xff0c;维护长度和描述&#xff0c; 激活&#xff0c;那么这个数据元素…

JavaSE-14笔记【反射机制(+2024新)】

文章目录 1.反射机制概述2.获取Class的四种方式3.通过反射机制实例化对象*4.反射机制结合配置文件灵活实例化对象*5.java.lang.reflect.Field5.1反编译类中的所有字段/属性5.2 通过反射机制给属性赋值* 6.java.lang.reflect.Method6.1反编译类中的所有方法6.2 通过反射机制调用…

变革 Perplexica:AI驱动的问答搜索引擎

Perplexica是一个开源的人工智能搜索工具&#xff0c;也可以说是一款人工智能搜索引擎&#xff0c;它深入互联网以找到答案。受Perplexity AI启发&#xff0c;它是一个开源选择&#xff0c;不仅可以搜索网络&#xff0c;还能理解您的问题。它使用先进的机器学习算法&#xff0c…

什么是环比折年率

环比折年率是月度&#xff08;或季度&#xff09;统计中一个十分重要的统计指标&#xff0c;由环比增速推算得到&#xff0c;用于反映经济的发展速度与趋势变化。环比折年率与同比增速相比具有对趋势变化灵敏度高的优点&#xff0c;在统计分析、趋势预测等领域有着广泛应用。 …

Docker-容器的前世今生

文章目录 Docker为什么产生&#xff1f;硬件虚拟化硬件虚拟化解决的问题硬件虚拟化定义硬件虚拟化技术虚拟机的优点虚拟机的缺点 操作系统虚拟化即容器容器化解决的问题容器化定义容器化技术历史 容器和虚拟机对比 Docker的发展历史Docker架构客户端服务端仓库Registry Docker重…

Linux工具篇 之 vim概念 操作 及基础指令讲解

学校不大 创造神话 讲桌两旁 陨落的王 临时抱佛脚 佛踹我一脚 书山有路勤为径 游戏玩的很起劲 想要计算机学的好&#xff0c;我的博客列表是个宝 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀…

这份详细的智慧校园建设方案,赶紧收藏

高等教育信息化是促进高等教育改革创新和提高质量的有效途径&#xff0c;是教育信息化发展的创新前沿。进一步加强基础设施和信息资源建设&#xff0c;重点推进信息技术与高等教育的深度融合&#xff0c;能促进教育内容、教学手段和方法现代化&#xff0c;创新人才培养、科研组…

渗透之sql注入---实战1

本期的sql注入实战在&#xff1a;BUUCTF在线评测 (buuoj.cn) 该网站上进行。 启动靶机&#xff1a; 1.进来后搜索web1 2.点击【SWPU2019】Web1启动靶机。 3.进来之后在此界面进行注入。 开始注入&#xff1a; 1.找注入点&#xff1a; 我们输入1 后查看广告详情发现报错&a…

我用suno做了人生中第一首歌

前几周AI已经杀入音乐制作领域&#xff0c;Suno正式发布V3音乐生成模型&#xff0c;被业界誉为AI音乐的"ChatGPT"时刻。 借此机会&#xff0c;我也生成了人生中第一首歌&#xff0c;下面是歌词和对应的音频。 歌词&#xff1a; [Verse] 烽火连天万里霜 英雄豪杰赴…

03-JAVA设计模式-解析器模式

解释器模式 什么是解析器模式 在Java中&#xff0c;解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;它给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xff0c;该解释器使用该表示来解释语言中的句子…

Linux提权--SUID提权内核漏洞本地用户提权

免责声明:本文仅做技术交流与学习,请不要乱搞破坏... 目录 SUID提权 漏洞成因 提权过程: 手工命令探针: 参考利用&#xff1a; 脚本探针: LinEnum.sh traitor linuxprivchecker等等... Linux命令的利用: find命令 利用nc反弹 利用python反弹--棱角 内核漏洞本地用…

电磁兼容(EMC):生产的ESD防护要点及措施

目录 1. 接地和连接系统 2. 操作员及工作区域 3. 地板 4. 座椅 5. 防静电车间 早期电子产品出现质量问题有80%的问题都是生产过程静电所引起的。随着ESD的管理程序系统的普及&#xff0c;ESD问题相当减小很多。例如当今的S20.20静电控制程序产生于IBM内部审核和控制系统。…

打不完!真的打不完!海量用户线索车企该怎么办?用AI!

当车企面临海量用户线索&#xff0c;怎么找到精准用户&#xff1f;大量的电话根本打不完&#xff0c;这种情况怎么办&#xff1f;建议借助AI&#xff0c;降本增效。下面以某车企为例来帮助大家解决这个难题&#xff01; 某车企面临的问题主要有三点 第一&#xff1a;车企有来自…

罗德与施瓦茨矢量网络分析仪ZNB20相位一致性

矢量网络分析仪(VNA)是电子测量领域中非常重要的一类仪器,广泛应用于射频和微波电路的测试与分析。其中,德国罗德与施瓦茨公司生产的ZNB20型号是一款性能出色的矢量网络分析仪,深受业内人士的青睐。本文将重点介绍ZNB20在相位测量方面的特点和优势,为用户提供全面的使用参考。 …