STL--list容器(链表)

2023-10-29

一、list基本概念

1. 功能:将数据进行链式存储

2. 链表

链表:

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

链表的组成:

        链表是由一系列结点组成

结点的组成:

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

3. 结构

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

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

 4. list优缺点:

list的优点:

  • 可以对任意位置进行快速插入或者删除
  • 采用动态存储分配,不会造成内存浪费和溢出
  • 链表执行插入和删除操作十分方便,修改指针即可,不需要大量移动数据

list的缺点:

  • 容器遍历速度没有数组快,占用空间比数组大
  • 链表灵活,但是空间(指针域)和时间(遍历)额外耗费比较大

5. 特别:

list容器的插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。

二、list构造函数

  • list<T>  lst;                             // list采用模板类实现,对象的默认构造方式
  • list(beg,  end);                        // 构造函数讲(beg,end)区间内的元素拷贝给本身
  • list(n,  elem);                          // 构造函数将n个elem拷贝给本身
  • list(const  list  &  lst);            // 拷贝构造函数
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
//遍历
void print_List(list<int> &l)
{
	for(list<int>::iterator it = l.begin();it!=l.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}
int main()
{
	list<int> l; // 默认构造

	// 添加数据
	l.push_back(10);
	l.push_back(20);
	l.push_back(30);
    l.push_back(40);
		l.push_back(50);
		// 遍历容器
	print_List(l);

	// 区间构造
	list<int>  L2(l.begin(),l.end());
	print_List(L2);

	// 拷贝构造
	list<int> L3(L2);
	print_List(L3);

	// n 个 elem 的方式
	list<int> L4(10,100);
	print_List(L4);
	return 0;
}

 三、list赋值和交换

  • assign(beg,  end);                                  // 将(beg,end)区间内的数据拷贝赋值给本身
  • assign(n,  elem);                                       // 将n个elem拷贝赋值给本身
  • list  operator=(const  list  &  lst);            // 重载等号操作符
  • swap(lst);                                                 // 将lst与本身的元素互换
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
//遍历
void print_List(list<int> &l)
{
	for(list<int>::iterator it = l.begin();it!=l.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}
int main()
{
	list<int> L1;
	for(int i=0;i<10;i++)
	{
		L1.push_back(i);
	}
	print_List(L1);

	// 赋值
	list<int> L2;
	L2 = L1;  // operator= 进行赋值
	print_List(L2);

	// assign 区间赋值
	list<int> L3;
	L3.assign(L2.begin(),L2.end());
	print_List(L3);

    // assign n 个 elem 的方式
	list<int> L4;
	L4.assign(10,100);
	print_List(L4);


	// 交换
	cout<<"交换前L3 和 L4:"<<endl;
    print_List(L3);
	print_List(L4);
	cout<<"交换后L3 和 L4:"<<endl;
	L3.swap(L4);
	print_List(L3);
	print_List(L4);
	return 0;

}

 四、list大小操作

  • size();                                  // 返回容器中元素的个数
  • empty();                             // 判断容器是否为空
  • resize(num);                       // 重新指定容器的长度为num,若容器变长,则以默认值0填充新的位置

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

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

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

	#include<iostream>
	#include<list>
	#include<algorithm>
	using namespace std;
	//遍历
	void print_List(list<int> &l)
	{
		for(list<int>::iterator it = l.begin();it!=l.end();it++)
		{
			cout<<*it<<" ";
		}
		cout<<endl;
	}
	int main()
	{
		list<int> L1;
		for(int i=0;i<10;i++)
		{
			L1.push_back(i);
		}
		print_List(L1);
	
		// 判断容器是否为空
		if(L1.empty())
		cout<<"L1 为空"<<endl;
		else
		cout<<"L1 不为空"<<endl;
	
	
		// 元素个数
		cout<<"L1 中元素的个数:"<<L1.size()<<endl;
	
		// 重新指定大小
		L1.resize(11); // 如果超出原本的大小,多出的部分默认由0 填充
		print_List(L1);
		L1.resize(15,99); // 重载版本,指定填充内容
		print_List(L1);
		L1.resize(6);
		print_List(L1); // 如果比原本的大小小,那么多出的部分被删除
		return 0;
	}

 五、list插入和删除

  • push_back(elem);             // 在容器尾部加入一个元素
  • push_front(elem);            // 在容器开头插入一个元素
  • pop_back();                       // 删除容器中最后一个元素
  • pop_front();                      // 删除容器第一个元素

  • insert(pos,  elem);                   // 在pos位置插入elem元素的拷贝,返回新数据的位置
  • insert(pos,  n,  elem);              // 在pos位置插入n个elem数据,无返回值
  • insert(pos,  beg,  end);            // 在pos位置插入(beg,end)区间内的数据,无返回值

  • erase(beg,  end);                      // 删除(beg,end)区间内的数据,返回下一个数据的位置
  • erase(pos);                               // 删除pos位置的数据,返回下一个数据的位置

  • remove(elem);                        // 删除容器中所有与elem值匹配的元素

  • clear();                                   // 移除容器中所有的数据
	#include<iostream>
	#include<list>
	#include<algorithm>
	using namespace std;
	//遍历
	void print_List(list<int> &l)
	{
		for(list<int>::iterator it = l.begin();it!=l.end();it++)
		{
			cout<<*it<<" ";
		}
		cout<<endl;
	}
	int main()
	{
		list<int> L1;
		for(int i=0;i<10;i++)
		{
			L1.push_back(i);
		}
		print_List(L1);
	
		// 头插
		L1.push_front(100);
		// 尾插
		L1.push_back(200);
		print_List(L1);
		/*
		头删
		L1.pop_front();
		尾删
		L1.pop_back();
		*/
	
		//insert 插入
		L1.insert(++L1.begin(),1000);  // 第一个参数是迭代器(位置),第二个参数是插入的内容
		print_List(L1); // 迭代器可以偏移
	
		// 删除
		L1.erase(L1.begin());  // 迭代器可以偏移
	    list<int>::iterator it = L1.begin(); // 设置it为迭代器
	    L1.erase(it);
		print_List(L1);
	
		// 移除
		L1.push_back(10000);
		print_List(L1);
		L1.remove(10000); // 移除list中所有的指定内容
		print_List(L1);
	
	    // 清空
	    L1.clear();
	    print_List(L1); // 清空所有的内容
		return 0;
	}

 六、list数据存取

list本质是链表,不是连续线性空间存储数据,迭代器也不支持随机访问

list不支持[]和at()访问

  • front();          // 返回第一个元素
  • back();               // 返回最后一个元素
	#include<iostream>
	#include<list>
	#include<algorithm>
	using namespace std;
	//遍历
	void print_List(list<int> &l)
	{
		for(list<int>::iterator it = l.begin();it!=l.end();it++)
		{
			cout<<*it<<" ";
		}
		cout<<endl;
	}
	int main()
	{
		list<int> L1;
		for(int i=0;i<10;i++)
		{
			L1.push_back(i);
		}
		print_List(L1);
	
	    // 访问第一个和最后一个元素
	    cout<<"第一个元素为:"<<L1.front()<<endl;
	    cout<<"最后一个元素为:"<<L1.back()<<endl;
	
		// 验证迭代器不能随机访问
		list<int>::iterator it = L1.begin();
		it++; // 只能++或者--不能+1
		return 0;
	}

 七、list反转和排序

  • reverse();            // 反转链表
  • sort();                       // 链表排序

	#include<iostream>
	using namespace std;
	#include<list>
	#include<algorithm>
	
	//遍历
	void print_List(list<int> &L)
	{
		for(list<int>::iterator it = L.begin();it!=L.end();it++)
		{
			cout<<*it<<" ";
		}
		cout<<endl;
	}
	
	// list容器的反转和排序
	void test01()
	{
		list<int> L1;
		for(int i=0;i<10;i++)
		{
			L1.push_back(i);
		}
		cout<<"反转前:"<<endl;
		print_List(L1);
	
		// 反转
		L1.reverse();
		cout<<"反转后:"<<endl;
		print_List(L1);
	}
	
	// 伪函数
	bool my_compare(int v1,int v2)
	{
		// 降序  --> 就让第一个数大于第二个数
		return v1 > v2;
	}
	
	void test02()
	{
		// 排序
		list<int> L2;
		L2.push_back(5);
		L2.push_back(78);
		L2.push_back(2);
		L2.push_back(98);
		L2.push_back(65);
		cout<<"排序前:"<<endl;
		print_List(L2);
		// sort(L2.begin(),L2.end()); // 所有不支持随机访问迭代器的容器,都不可以用标准算法
		// 不支持随机访问的迭代器的容器,内部会对应提供一些算法
		L2.sort(); // 默认升序
		cout<<"升序排序后:"<<endl;
		print_List(L2);
	
		L2.sort(my_compare); // 降序的操作
		cout<<"降序排列后:"<<endl;
	 	print_List(L2);
	}
	int main()
	{
		test01();
		test02();
		return 0;
	} 

八、附加一个排序案例

	#include<iostream>
	using namespace std;
	#include<list>
	#include<algorithm>
	
	class person
	{
	public:
		person(string name,int age,int height)
		{
			this->name=name;
			this->age=age;
			this->height=height;
		}
		string name;
		int age;
		int height;
	};
	
	void print_list(list<person>&L)
	{
		for(list<person>::iterator it=L.begin();it!=L.end();it++)
		{
			cout<<"姓名:"<<it->name<<"\t年龄:"<<it->age<<"\t身高:"<<it->height<<endl;
		}
	}
	
	bool compare_person(person &p1,person &p2)
	{
		// 按照身高降序
		if(p1.age==p2.age)
		return p1.height>p2.height;
		// 按年龄升序
		return p1.age<p2.age;
	}
	
	void test01()
	{
		list<person> L;
		person p1("刘备",35,175);
		person p2("曹操",45,180);
		person p3("孙权",40,170);
		person p4("赵云",25,190);
		person p5("张飞",35,189);
		person p6("关羽",35,200);
	
		L.push_back(p1);
		L.push_back(p2);
		L.push_back(p3);
		L.push_back(p4);
		L.push_back(p5);
		L.push_back(p6);
	
		// 排序前
		print_list(L);
	
		// 排序后
		cout<<"按年龄排序后:"<<endl;
		// 操作自定义类型的数据排序要指定排序的规则
		L.sort(compare_person);
		print_list(L);
	
		// 重新定义排序,在年龄相同的情况下,按照身高进行降序排列
		cout<<"多重条件后的排序:"<<endl;
		L.sort(compare_person);
		print_list(L);
	}
	int main()
	{
		test01();
		return 0;
	}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STL--list容器(链表) 的相关文章

  • 如何在 C++ 中的文件末尾添加数据?

    我已按照网上的说明进行操作 此代码应该将输入添加到文件 数据库 的末尾 但当我检查时 数据会覆盖现有数据 请帮忙 这是我的代码 int main string name string address string handphone cou
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 如何在 C# 中定义文本框数组?

    您好 当我在 Windows 申请表上创建文本框时 我无法将其命名为 box 0 box 1 等 我这样做的目的是因为我想循环使用它们 其实我发现TextBox array firstTextBox secondTextBox 也有效
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • 如何将自定义 JSON 文件添加到 IConfiguration 中?

    我正在使用 asp net Autofac 我正在尝试加载自定义 JSON 配置文件 并基于该文件创建 实例化 IConfiguration 实例 或者至少将我的文件包含到默认情况下构建的 IConfiguration asp net 中
  • 私有模板函数

    我有一堂课 C h class C private template
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • 如何在 C# 中调整图像大小同时保持高质量?

    我从这里找到了一篇关于图像处理的文章 http www switchonthecode com tutorials csharp tutorial image editing saving cropping and resizing htt
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个

随机推荐

  • MNE-Python工具箱使用raw.plot绘图时遇到问题

    使用MNE Python工具箱进行脑电数据分析时绘图的代码如下所示 import matplotlib import pathlib import mne matplotlib use Qt5Agg 加载原始数据及其路径 raw path
  • github里的默认域_渗透基础——域用户的密码永不过期属性

    0x00 前言 在域环境中 域用户的凭据是十分重要的信息 为了增强安全性 域组策略会设置所有域用户口令的最长有效时间 到达过期时间后强制用户更改口令 在实际环境中 有些域用户需要设置为密码永不过期 这可以通过添加密码永不过期属性来实现 在域
  • Linux系统中Qt程序指定位置加载库文件的四种方式

    这边提供四种方法 方法一 环境变量临时加载 export LD LIBRARY PATH home yjd code mylib 这种方式在终端退出后就会失效 方法二 配置环境变量到当前用户的 profile文件中 在 profile文件末
  • python 爬虫(一) requests+BeautifulSoup 爬取简单网页图片代码示例

    最近学习了Python 借助各个大神的文章 自己写了以下代码 来爬取网页图片 希望可以帮助到大家 工具是 idea coding utf 8 import requests from bs4 import BeautifulSoup imp
  • Linux虚拟机安装及其注意事项!

    Linux虚拟机安装及其注意事项 安装须知 装前必看 一 安装虚拟机 二 安装操作系统 总结 安装须知 装前必看 本次安装为运用VMware workstation虚拟机软件在物理机上进行安装 本次安装为RedHat Enterprise
  • Swift5.0 WKWebView中的JS交互

    好的团队离不开大家的默契合作 在开发中经常遇到H5和移动端合作的业务 在开发中JS交互是非常常见的 小萌现在的主打语言是Swift 所以封装一下Swift版的JS交互 完整代码 在此之前加入协议WKNavigationDelegate WK
  • C# winform流程图(功能超完整附下载链接)

    C winform流程图 功能超完整 工具箱 文件存储打开 画布放大缩小 图元操作 操作步骤 可撤销 图元属性调节 点我下载项目源码 1 工具箱创建图元 矩形 菱形 圆 直线 曲线 其他图形可以自行仿照开发 2 图元有六个操纵柄 四个连接点
  • vs2008编译live555源码

    1解决方案编译方式 1 1简介 Live555 是一个为流媒体提供解决方案的跨平台的C 开源项目 它实现了对标准流媒体传输协议如RTP RTCP RTSP SIP等的支持 Live555实现了对多种音视频编码格式的音视频数据的流化 接收和处
  • cudnn配置

    2019独角兽企业重金招聘Python工程师标准 gt gt gt cudnn cuda config sudo cp cuda include cudnn h usr local cuda include sudo cp cuda lib
  • L2-029 特立独行的幸福

    对一个十进制数的各位数字做一次平方和 称作一次迭代 如果一个十进制数能通过若干次迭代得到 1 就称该数为幸福数 1 是一个幸福数 此外 例如 19 经过 1 次迭代得到 82 2 次迭代后得到 68 3 次迭代后得到 100 最后得到 1
  • 使用python实现自动点击功能

    猜你感兴趣 使用Pyqt5玩转ChatGpt 内网文件共享服务 快速搭建私有pip镜像源 python设计模式 创建型模式 docker搭建私有git服务器 项目备份和迁移 redis持久化方案 被测点击界面 新建counter html添
  • CDH简介及CDH部署、原理和使用介绍( 版本6.3.1 )

    CDH简介及CDH部署 原理和使用介绍 版本6 3 1 第一章 CDH简介 CDH概念 CDH是Cloudera的100 开源平台发行版 包括Apache Hadoop 专为满足企业需求而构建 CDH提供开箱即用的企业使用所需的一切 通过将
  • python 模型 ORM简介

    Django之ORM Object Relational Mapping ORM 一 ORM介绍1 ORM概念 对象关系映射模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术 2 ORM由来 让我们从O R开始 字母O起源于
  • 菜狗杯Misc你会异或吗wp

    题目给出提示 神秘数字0x50 下载附件后是一个打不开的png 用010打开看下内容 结合异或和0x50的提示 可以发现0xD9 0x50 0x89 0x00 0x50 0x50 0x1E 0x50 0x4E 所以很明显了文件开头应该恢复成
  • 【AI实战】开源可商用的中英文大语言模型baichuan-7B,从零开始搭建

    AI实战 开源可商用的中英文大语言模型baichuan 7B 从零开始搭建 baichuan 7B 简介 baichuan 7B 中文评测 baichuan 7B 搭建 参考 baichuan 7B 简介 baichuan 7B 是由百川智
  • Linux动态库(一)之同名符号

    万事皆有缘由 还是先从我遇到的这个问题说起 问 有一个主执行程序main 其中实现了函数foo 同时调用动态库liba so中的函数bar 而动态库liba so中也实现了foo 函数 那么在执行的时候如果在bar 中调用foo 会调用到哪
  • TypeScript(单独运行ts、webpack运行ts)

    TypeScript是一门编程语言 完全兼容JavaScript 是JavaScript的超集 引入类型系统 可以尽早的定位错误位置 提升开发效率 全局安装typescript环境 npm i g typescript 检查是否安装成功以及
  • 如何解决netty自定义协议粘包分包问题

    又一次发现公司同事用netty竟然都不处理粘包分包的问题 出了问题都不知道怎么回事 呵呵哒 sp厂商反馈数据已推送至我方提供的地址 但未收到我方的应答 正常推送了一次 又重试三次 都没有收到我方应答 看了下代码 又跟踪了几条日志 发现sp数
  • 【09】MySQL:MHA + Atlas 实现读写分离高可用

    写在前面的话 前面做了 MHA 高可用 但是存在这样一个问题 我们花了 4 台机器 但是最终被利用起来的也就一台 主库 这样硬件利用率才 25 这意味着除非发生故障 不然其他几台机器都是摆设 明显的资源浪费 那么有没有一种办法把这些机器利用
  • STL--list容器(链表)

    一 list基本概念 1 功能 将数据进行链式存储 2 链表 链表 是一种物理存储单元上非连续的存储结构 数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成 链表是由一系列结点组成 结点的组成 一个是存储数据元素的数据域 另一个是存