链表保姆级精讲

一.什么是list

在 C++ 中,std::list 是标准库提供的一个容器类,用于将数据进行链式存储。链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。

1.链表的组成:链表由一系列结点组成。
2.结点的组成:1.存储数据元素的数据域 2.存储下一个结点地址的指针域。


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

二.list与vector的区别

底层实现:

list 是由双向链表实现的,每个元素包含指向前一个和后一个元素的指针。这种实现使得在列表中的任意位置插入和删除元素都是高效的,但对于随机访问元素的性能较差。
vector 是由动态数组实现的,元素在内存中是连续存储的。这种实现使得随机访问元素的性能非常好,但在中间或开头插入/删除元素时会涉及元素的移动,性能相对较低。


动态调整大小:

list 的大小可以动态增长和缩小,因为它使用链表来存储元素,插入和删除操作的性能与列表的大小无关。
vector 的大小也可以动态增长,但在需要重新分配内存时,可能会导致大量的元素复制和内存重分配操作。
访问效率:

list 不支持随机访问,只能通过迭代器进行顺序访问。对于需要频繁插入和删除操作的场景,list 的性能更好。
vector 支持随机访问,可以通过下标直接访问元素。对于需要频繁的随机访问操作,vector 的性能更好。
内存占用:

list 在存储元素时,除了元素本身的值外,还需要额外的空间存储指向前一个和后一个元素的指针。因此,它通常比 vector 使用更多的内存。
vector 在存储元素时,只需要存储元素的值本身和一些额外的控制信息,因此通常比 list 使用更少的内存。
插入和删除操作:

list 对于在任意位置插入和删除元素来说是高效的,因为它只需要修改相邻元素的指针即可,不需要移动其他元素。list 有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector中是不成立的。
vector 对于在末尾插入和删除元素来说是高效的,因为它只需要在数组的末尾进行操作,不需要移动其他元素。但在中间或开头插入/删除元素时,需要移动其他元素。
综上所述,选择使用 list 还是 vector 取决于具体的应用场景和需求。如果需要频繁的插入和删除操作,并且不需要频繁的随机访问元素,可以选择 list。如果需要频繁的随机访问元素,而插入和删除操作较少,可以选择 vector。另外,如果需要在容器的中间位置进行插入和删除操作,并且对访问效率要求不高,可以考虑使用 list。

三.list构造函数

示例:

#include <iostream>
#include <list>     //必须包含该头文件
using namespace std;

void printVec(list<int> &v)
{
	for (list<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}
void printVec(list<double> &v)
{
	for (list<double>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	list<int> v1;
	v1.push_back(10);  //添加元素
	v1.push_back(20);
	printVec(v1);

	list<int> v2(v1.begin(), v1.end());
	printVec(v2);

	list<double> v3(5, 6.32);
	printVec(v3);

	list<double> v4(v3);
	printVec(v4);
}

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

结果:

//result
10 20
10 20
6.32 6.32 6.32 6.32 6.32
6.32 6.32 6.32 6.32 6.32

注意:list 作为函数的参数或者返回值时,不能缺少其中的“&”。

四.赋值

示例:

#include <iostream>
#include <list>     //必须包含该头文件
using namespace std;

void printVec(list<int> &v)
{
	for (list<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	list<int> v1;
	v1.push_back(10);  //添加元素
	v1.push_back(20);
	printVec(v1);

	list<int> v2 = v1;
	printVec(v2);

	list<int> v3;
	v3.assign(v1.begin(), v1.end());
	printVec(v3);

	list<int> v4;
	v4.assign(6, 1);
	printVec(v4);
}

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

结果:

//result
10 20
10 20
10 20
1 1 1 1 1 1

五.与list长度有关的操作

示例:

#include <iostream>
#include <list>     //必须包含该头文件
using namespace std;

void printVec(list<int> &v)
{
	for (list<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	list<int> v1;
	if (v1.empty())     //判断是否为空
	{
		cout << "当前v1为空!" << endl;
	}

	v1.push_back(10);  //添加元素
	v1.push_back(20);
	v1.push_back(30);

	if (!v1.empty())
	{
		cout << "v1中元素个数:" << v1.size() << endl;
		printVec(v1);
	}

	v1.resize(5);
	printVec(v1);

	v1.resize(10, 1);
	printVec(v1);
}

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

结果:

//result
当前v1为空!
v1中元素个数:3
10 20 30
10 20 30 0 0
10 20 30 0 0 1 1 1 1 1

六.list的插入与删除

示例:

#include <iostream>
#include <list>     //必须包含该头文件
using namespace std;

void printVec(list<int> &v)
{
	for (list<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	list<int> v1;
	v1.push_back(1);  //尾部添加元素
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(3);
	cout << "尾部添加元素: " << endl;
	printVec(v1);

	v1.pop_back();    //尾部删除元素
	cout << "尾部删除元素: " << endl;
	printVec(v1);

	v1.push_front(100);  //头部添加元素
	v1.push_front(200);
	v1.push_front(300);
	cout << "头部添加元素: " << endl;
	printVec(v1);

	v1.pop_front();   //头部删除元素
	v1.pop_front();
	cout << "头部删除元素: " << endl;
	printVec(v1);

	v1.insert(v1.begin(), 100);      //插入元素100
	cout << "插入元素100: " << endl;
	printVec(v1);

	v1.insert(v1.begin(), 5, 100);   //插入5个元素100
	cout << "插入5个元素100: " << endl;
	printVec(v1);

	v1.erase(v1.begin());    //删除元素
	cout << "删除元素v1.begin(): " << endl;
	printVec(v1);

	v1.remove(100);
	cout << "删除所有100元素: " << endl;
	printVec(v1);

	v1.clear();				 //清空容器
	printVec(v1);
}

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

结果:

//result
尾部添加元素:
1 2 3 3
尾部删除元素:
1 2 3
头部添加元素:
300 200 100 1 2 3
头部删除元素:
100 1 2 3
插入元素100:
100 100 1 2 3
插入5个元素100:
100 100 100 100 100 100 100 1 2 3
删除元素v1.begin():
100 100 100 100 100 100 1 2 3
删除所有100元素:
1 2 3

七.获取list表中的数据

示例:

#include <iostream>
#include <list>     //必须包含该头文件
using namespace std;

void test01()
{
	list<int> v1 = { 1, 2, 3, 4, 5, 6 };
	cout << "v1.front() = " << v1.front() << endl;
	cout << "v1.back() = " << v1.back() << endl;
}

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

结果:

//result
v1.front() = 1
v1.back() = 6

八.list的互换、反转、排序

示例:
 

#include <iostream>
#include <list>     //必须包含该头文件
using namespace std;

void printVec(list<int> &v)
{
	for (list<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	list<int> v1 = { 9, 5, 7, 8, 6 };
	list<int> v2 = { 5, 4, 3, 2, 1 };

	v1.swap(v2);   //互换v1与v2中的元素
	cout << "list v1 : " ;
	printVec(v1);
	cout << "list v2 : " ;
	printVec(v2);

	v2.sort();  //链表排序
	cout << "v2链表排序 : ";
	printVec(v2);

	v2.reverse();  //反转链表v2
	cout << "v2反转链表 : ";
	printVec(v2);
}

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

结果:

//result
list v1 : 5 4 3 2 1
list v2 : 9 5 7 8 6
v2链表排序 : 5 6 7 8 9
v2反转链表 : 9 8 7 6 5

综上,list更倾向于当你在中间等位置进行多项插入和删除操作时经常用到的。

至此,完结撒花!!!

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值