【C++】深入理解List:双向链表的应用

凭时间赢来的东西,时间肯定会为之作证。

前言

这是我自己学习C++的第七篇博客总结。后期我会继续把C++学习笔记开源至博客上。

上一期笔记是关于C++的vector类知识,没看的同学可以过去看看:【C++】探索Vector:灵活的数据存储解决方案-CSDN博客https://blog.csdn.net/hsy1603914691/article/details/145553176

list类的介绍

  1. 在使用list类 时,必须包含**#include <list>** 这一行。

2.string类 的底层其实是一个储存字符的顺序表结构 ,而vector类 的底层是一个顺序表模板 ,使用时需要显示实例化 ,而list类 的底层是一个双向链表模板 ,使用时也需要显示实例化 ,后面的笔记中以整形 为例。

  1. 下面是list类 的官方文本介绍,里面有详细的用法讲解。

cplusplus.com/reference/list/list/?kw=listhttps://cplusplus.com/reference/list/list/?kw=list

list类对象的常见构造

1.list<int> l1 ,什么也不需要传入,构造一个空的list类对象。

2.list<int> l2(n,num) ,构造一个list类对象,里面包含n个num整形。

3.list<int> l3(l2.begin(),l2.end()) ,使用另一个list类对象进行迭代器构造。

  1. list<int> l4(l3) ,使用另一个list类对象进行构造。
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1;
	list<int> l2(5, 1);
	list<int> l3(l2.begin(), l2.end());
	list<int> l4(l3);
	for (auto a : l1)
	{
		cout << a << " ";
	}
	cout << endl;
	for (auto a : l2)
	{
		cout << a << " ";
	}
	cout << endl;
	for (auto a : l3)
	{
		cout << a << " ";
	}
	cout << endl;
	for (auto a : l4)
	{
		cout << a << " ";
	}
	cout << endl;
	return 0;
}
//
//1 1 1 1 1
//1 1 1 1 1
//1 1 1 1 1
  1. list类对象的初始化分为两种。

  2. 如果使用**=号,则为拷贝初始化**;如果不使用**=号,则为直接初始化**。

  3. list类对象的初始化时,需要使用大括号包裹初始化值。

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1 = { 1,2,3,4,5 };
	list<int> l2({ 5,6,7,8,9 });
	for (auto a : l1)
	{
		cout << a << " ";
	}
	cout << endl;
	for (auto a : l2)
	{
		cout << a << " ";
	}
	cout << endl;
	return 0;
}

list类对象的容量操作

  1. list.size() ,返回list类对象 中有效节点 的个数。

2.list.empty() ,检测list类对象的有效大小是否为0,为0返回true,不为0返回flase。

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1 = { 1,2,3,4,5 };
	list<int> l2({ 5,6,7,8,9 });
	cout << l1.size() << endl;//5
	cout << l2.empty() << endl;//0
	return 0;
}

list类对象的修改操作

1.list.push_back(num) ,在list类对象中尾插整数num。

  1. list.pop_back(),在list类对象中尾删。

3.list.push_front(num) ,在list类对象的首元素之前****插入 一个元素num 。

  1. list.pop front(),删除list类对象的首元素 。

5.list.insert(pos_iterator,n,num)****,在下标为pos位置的元素的前面插入n个数字num。

  1. list.erase(pos_iterator),删除下标为pos位置的元素的上的数字,如果需要删除一串数字,则再给一个截至迭代器。

  2. list.swap(v2),交换两个list类对象的值****。

list类对象的返回值操作

  1. list.front(),返回list类对象的第一个节点 的值引用 。

  2. list.back(),返回list类对象的最后一个节点 的值引用 。

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1 = { 1,2,3,4,5 };
	cout << l1.front() << endl;
	cout << l1.back() << endl;
	return 0;
}

list类对象的遍历操作

  1. 由于vector类对象 和string类对象 的底层都是顺序表 ,所以** ** 都可以进行重构 ;而list类对象 的底层是链表 ,所以** ** 不能进行重构,即无法使用 。

  2. list.begin() 、list.end() ,vector.begin() 获取第一个节点的迭代器,string.end() 获取最后一个节点的下一个位置的迭代器。

  3. list.rbegin() 、list.rend() ,list.rbegin() 获取头节点 的迭代器,vector.rend()获取第一个节点 的迭代器。

  4. 注意反向迭代器 进行迭代的步骤也是**++** ,反向迭代器是用来反向遍历链表 的。

  5. 范围for循环 ,用于有范围的集合进行遍历,C++11 中引入了基于范围的for循环 。for循环 中的括号由冒号" : " 分为两部分:第一部分是用于迭代的变量 (可以使用auto 让编译器自动判断变量类型),第二部分则表示被迭代的范围 。(自动迭代,自动取数据,自动判断结束。 )

  6. 范围for循环 ,如果需要对范围对象进行修改 ,则使用auto& 来修饰迭代的变量;如果需要对较大的目标对象进行遍历 ,也可以使用auto& 来修饰迭代的变量。

  7. 范围for循环 ,是用于遍历容器的,它的底层也是迭代器 。(数组也可以用范围for循环。 )

cpp 复制代码
//迭代器
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1 = { 1,2,3,4,5 };
	auto lt = l1.begin();
	while (lt != l1.end())
	{
		cout << *lt << " ";
		lt++;
	}
	return 0;
}
cpp 复制代码
//反向迭代器
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1 = { 1,2,3,4,5 };
	auto lt = l1.rbegin();
	while (lt != l1.rend())
	{
		cout << *lt << " ";
		lt++;
	}
	return 0;
}
cpp 复制代码
//for循环
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> l1 = { 1,2,3,4,5 };
	list<int> l2({ 5,6,7,8,9 });
	for (auto a : l1)
	{
		cout << a << " ";
	}
	cout << endl;
	for (auto& a : l2)
	{
		cout << a << " ";
	}
	cout << endl;
	return 0;
}

致谢

感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!

相关推荐
東隅已逝,桑榆非晚2 分钟前
算法2. 双指针法-复写零
c++·笔记·学习·算法
布莱克6053 分钟前
C++ 中堆和栈的区别详解
开发语言·c++·栈·堆
誰能久伴不乏1 小时前
用 UDP 做一条“可靠“的控制通道
c++·qt·网络协议·udp
十五年专注C++开发1 小时前
FlatBuffers: 一个高效的零拷贝二进制序列化库
c++·序列化·反序列化·flatbuffers
xys_6782 小时前
深挖C++:C++入门基础
开发语言·c++
高冷小鱼殿下2 小时前
C 语言指针与输入输出
c++
路溪非溪3 小时前
C++标准库之智能指针
linux·开发语言·c++
hetao17338373 小时前
2026-11-02 hetao1733837 的刷题记录
c++·算法
Tairitsu_H3 小时前
[C++高阶数据结构·图论下] 最短路径:为什么“挑最小的”一定正确?
数据结构·c++·图论
weixin199701080164 小时前
官方授权通道和灰色爬虫,做数据服务该选哪条路(附 python 源码)
c++·爬虫·python