IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 一篇文章全面理解C++STL中的list容器(附实战练习——学生成绩管理系统) -> 正文阅读

[系统运维]一篇文章全面理解C++STL中的list容器(附实战练习——学生成绩管理系统)

1.list容器基本概念

(1)list容器实际上就是一个链表,不同于vector容器,list容器是通过指针将数据链式储存起来;

在这里插入图片描述

(2)链表是由一系列结点组成的,每一个结点由储存数据的数据域和储存下一个数据的地址的指针域组成;

链表的知识在之前的文章中**线性表的链式存储结构 ( 链表 ).**

list容器中的链表是一个双向循环链表,如下图所示;

在这里插入图片描述

(1)list的优缺点

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

1 .list链表的访问不支持随机访问,只能使用迭代器访问,操作较复杂
2 . 链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大,遍历速度没有数组快,且占用空间比数组大。
3 . list有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。

好了,理论知识就到这里,我们主要靠实战举例理解

2.创建list容器

构造函数原型:(和vector基本相同)

list<T> lst; //list默认构造形式:
list(begin,end); //构造函数将[begin, end)区间中的元素拷贝给本身。
list(n,e); //构造函数将n个e赋给给本身。
list(const list &lst); //拷贝构造函数

示例

#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相应头文件

void showList01(const list<int>& L) //唯一一种方式打印list容器中的数据,因为list容器只能通过迭代器访问
{

	for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
		cout << *p << " ";
	}
	cout << endl;
}
void testit()
{
	list<int>L1;
	for (int i = 3; i < 50; i += 10)
	{
		L1.push_back(i);
	}
	

	showList01(L1);

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

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

	list<int>L4(10, 666);
	showList01(L4);
}

int main() {

	testit();

	system("pause");

	return 0;
}

运行结果
在这里插入图片描述

3.list容器赋值和交换

接口函数原型(和vector基本相同)

assign(begin, end); //将[begin, end)区间中的数据赋值给容器。
assign(n, t); //将n个t拷贝赋值给本身。
list& operator=(const list &lst); //重载等号操作符
swap(lst); //将lst与本身的元素互换。

示例

#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相应头文件

void showList01(const list<int>& L) //唯一一种方式打印list容器中的数据,因为list容器只能通过迭代器访问
{

	for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
		cout << *p << " ";
	}
	cout << endl;
}

//赋值和交换
void testit01()
{
	list<int>L1;
	for (int i = 3; i < 50; i += 10)
	{
		L1.push_back(i);
	}
	showList01(L1);

	//赋值
	list<int>L2;
	L2 = L1;
	showList01(L2);

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

	list<int>L4;
	L4.assign(10, 33);
	showList01(L4);

}

//交换
void testit02()
{

	list<int>L1;
	for (int i = 3; i < 50; i += 10)
	{
		L1.push_back(i);
	}
	list<int>L2;
	L2.assign(10, 66);

	cout << "交换前: " << endl;
	showList01(L1);
	showList01(L2);

	cout << endl;

	L1.swap(L2);

	cout << "交换后: " << endl;
	showList01(L1);
	showList01(L2);

}

int main() {

	testit01();

	cout << "***********下一个测试案例**********" << endl;

	testit02();

	system("pause");

	return 0;
}

运行结果
在这里插入图片描述

4.list大小操作

接口函数原型(和vector基本相同)

size(); //返回容器中元素的个数

empty(); //判断容器是否为空

resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

? //如果容器变短,则末尾超出容器长度的元素被删除。

resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。若容器变短,则删除多余的部分

示例

#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相应头文件

void showList01(const list<int>& L) //唯一一种方式打印list容器中的数据,因为list容器只能通过迭代器访问
{

	for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
		cout << *p << " ";
	}
	cout << endl;
}

//大小操作
void testit01()
{
	list<int>L1;
	for (int i = 3; i < 50; i += 10)
	{
		L1.push_back(i);
	}
	showList01(L1);

	if (L1.empty())
	{
		cout << "L1为空" << endl;
	}
	else
	{
		cout << "L1不为空" << endl;
		cout << "L1的大小为: " << L1.size() << endl;
	}

	//重新指定大小
	L1.resize(10);
	showList01(L1);

	L1.resize(2);
	showList01(L1);
}

int main() {

	testit01();

	system("pause");

	return 0;
}

运行结果
在这里插入图片描述

5.list插入和删除

接口函数原型.(和vector有区别点)

push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
//pos为迭代器位置
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
//pos为迭代器位置
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
//pos为迭代器位置
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
//beg,end为迭代器,也可通过迭代器++改变区间
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。

示例

#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相应头文件

void showList01(const list<int>& L) //唯一一种方式打印list容器中的数据,因为list容器只能通过迭代器访问
{

	for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
		cout << *p << " ";
	}
	cout << endl;
}


//插入和删除
void testit01()
{
	list<int> L;
	//尾插fa
	L.push_back(11);
	L.push_back(22);
	L.push_back(33);
	//头插af
	L.push_front(150);
	L.push_front(250);
	L.push_front(350);

	showList01(L);

	//尾删fa
	L.pop_back();
	showList01(L);

	//头删fa
	L.pop_front();
	showList01(L);

	//插入fa
	list<int>::iterator p = L.begin();
	L.insert(++p, 888);
	showList01(L);

	//删除af
	p = L.begin();
	L.erase(++p);
	showList01(L);

	//移除fa
	L.push_back(9999);
	L.push_back(9999);
	L.push_back(999);
	showList01(L);
	L.remove(9999);
	showList01(L);

	//清空fa
	L.clear();
	showList01(L);
}

int main() {

	testit01();

	system("pause");

	return 0;
}

运行结果
在这里插入图片描述

6.list数据存取

接口函数原型:

front()//返回第一个数据
back()//返回第二个数据
//只能通过迭代器访问

示例

#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相应头文件

//数据存取
void testit01()
{
	list<int>L1;
	for (int i = 3; i < 50; i += 10)
	{
		L1.push_back(i);
	}

	//list不支持at访问数据和[]方式访问数据
	//只能通过迭代器访问
	cout << "第一个元素为: " << L1.front() << endl;
	cout << "最后一个元素为: " << L1.back() << endl;

	//list容器的迭代器是双向迭代器,不支持随机访问

	list<int>::iterator it = L1.begin();

	//it = it + 1;//错误,不可以跳跃访问,即使是+1

	it++;
	cout << "第二个元素为: " << *it << endl;
	it++;
	cout << "第三个元素为: " << *it << endl;
}

int main() {

	testit01();

	system("pause");

	return 0;
}


7.list反转和排序

接口函数原型

reverse(); //反转链表
sort(); //链表排序
//两者都不是STL中的算法函数,而是list容器中自带的接口函数,用法也并不相同

示例

#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相应头文件

void showList01(const list<int>& L) //唯一一种方式打印list容器中的数据,因为list容器只能通过迭代器访问
{

	for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
		cout << *p << " ";
	}
	cout << endl;
}


bool My_sortway(int a, int b)
{
	return a > b;
}

//反转和排序
void test01()
{
	list<int> L;
	L.push_back(99);
	L.push_back(33);
	L.push_back(22);
	L.push_back(77);
	showList01(L);

	//反转容器的元素
	L.reverse();
	cout << "反转后 :";
	showList01(L);

	//排序
	L.sort(); //默认的排序规则 从小到大
	cout << "从小到大排序后 :";
	showList01(L);

	L.sort(My_sortway); //指定规则,从大到小
	cout << "从大到小排序后 :";
	showList01(L);
}

int main() {

	test01();

	system("pause");

	return 0;
}

运行结果
在这里插入图片描述

list实战(学生成绩管理系统)

题目要求:
1 .制作一个学生成绩单管理系统
2 .将student自定义数据类型进行排序,student中属性有姓名、年龄、语文成绩,数学成绩,英语成绩
排序规则:按照总成绩sum进行降序,如果总成绩sum相同按照语文成绩进行降序

源代码

#include<iostream>
using namespace std;
#include <list>
#include <string>

class Student {
public:
	Student(string name, int ch, int ma,int e) {
		m_Name = name;
		chinese = ch;
		math = ma;
		English = e;
		sum = ch + ma + e;
	}

public:
	string m_Name;  //姓名
	int chinese;      //语文成绩
	int math;   //数学成绩
	int English;//英语成绩
	int sum;//总成绩

};


bool ComparePerson(Student& p1, Student& p2)//定义sort排序从大到小
{

	if (p1.sum == p2.sum) {
		return p1.sum < p2.sum;
	}
	else
	{
		return  p1.chinese < p2.chinese;
	}

}

void test() {

	list<Student> k;

	Student p1("杜雯菲", 88,77,95);
	Student p2("杜蚊分", 67,58,26);
	Student p3("李八八", 95,77,88);
	Student p4("赵二蛋",86,75,68);
	Student p5("王小牛", 86,46,86);
	Student p6("张小哈",89,57,68);

	k.push_back(p1);
	k.push_back(p2);
	k.push_back(p3);
	k.push_back(p4);
	k.push_back(p5);
	k.push_back(p6);

	for (list<Student>::iterator it = k.begin(); it != k.end(); it++) {
		cout << "姓名: " << it->m_Name << " 语文: " << it->chinese
			<< " 数学: " << it->math << " 英语: " << it->English<< "  总成绩: " << it->sum<<  endl;
	}

	cout << "---------------------------------" << endl;
	k.sort(ComparePerson); //排序
	cout << "排序后" << endl;
	for (list<Student>::iterator it = k.begin(); it != k.end(); it++) {
		cout << "姓名: " << it->m_Name << " 语文: " << it->chinese
			<< " 数学: " << it->math << " 英语: " << it->English << "  总成绩: " << it->sum << endl;
	}
}

int main() {

	test();

	system("pause");

	return 0;
}

运行结果
在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:23:11  更:2022-01-01 14:24:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 6:40:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码