List——stl

本文详细介绍了C++中list数据结构的操作,包括构造函数、增删改查、属性、交换、反转、排序及合并等。list本质上是双向链表,支持快速插入和删除,而vector则适合随机访问和尾部快速添加。文章通过实例展示了如何使用list的各种方法,如insert、erase、sort、merge等,并强调了在自定义类型中重载运算符的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

list的本质就是一个双向链表,操作都是依据与数据结构

forward list :向前链表,他的操作都是在链表头里

  • 添加节点时,forword list 相较于list的效率高一点点,因为list有一个size的++的操作

  • list和vector的区别

  • vector随机访问很快,尾添加很快,不支持快速插入删除

  • list随机访问慢,也支持下标支持快速插入和删除

list构造函数初始化

定义一个int类型色list对象,需要添加头文件:#include <list>

  • 无参构造
list<int> ls;
  • 有参构造
    list没有赋值的对象默认初始值为0, int类型会初始为数字类型的0,char类型会初始为char类型的0。
    定义一个结构体类型的历史的对象。
 Note是一个结构体类型,里面有一个int a,char b 
list<node> ls(5)void fun(Node& d)
{
	cout << d.a << " " << d.c << "\n";
}
开头和结尾都是
for_each(ls.begin(), ls.end(), fun);

  • 另一个对象给一个对象初始化
list<node> ls2(ls1) ;
  • 迭代器定义
list<node> ls1;
list<node>::iterator ite = ls1.begin();

迭代器可以进行++操作,但是不能+2,因为迭代器是一个非连续的空间

迭代器ite

ite++ ; //可以
ite+2 ; // 不行

属性

list没有容量,但是有大小

返回大小:size

node no  = {12,'a'};
list<node> ls(6,no) ;

cout << ls.size() << endl ; //返回大小 6
  • resize:重新设置元素个数,容量不变,如果重新设置了一个小的,那么会截断原来的数据
list<Node> ls(6, no);

cout << ls.size() << endl;

ls.resize(0);

判断list对象是否为空,为空的话是1,不为空的话为0

node no  = {12,'a'};
list<Node> ls(6, no);
cout << ls.empty() << endl; // 不为空返回0

增删改查

添加

头添加:push_front,尾添加:push_back,中间添加:insert
中间添加,多个的话就是就是三个参数

struct Node
{
	int a;
	char c; // 0 

	Node(int d, char e)
	{
		a = d;
		c = e;
	}
};

头添加和尾添加
	list<Node> ls;
	ls.push_front(Node(12, 'a'));  // 头添加
	ls.push_front(Node(13, 'b'));  // 头添加 , 这个是最终的头
	ls.push_back(Node(14, 'c'));   // 尾添加

中间添加(添加一个元素)
	list<Node>::iterator ite = ls.begin();
	ite++;
	ls.insert(ite, Node(15, 'd')); // 中间添加,前面的++操作,会使这个添加加到第二个位置
	
	ls.insert(ite, 3, Node(16, 'e'));

中间添加(添加多个元素)
	ls.insert(ite,3,Node(13,'r')) ; // 添加三个13,r

删除、修改

删除

简答的用法:

	list<Node>::iterator ite = ls.begin();
	ite++;
	
用begin	
	ls.erase(ite); // 会删除ls的第二个
用end
	ls.erase(--ls.end());  // 会删除最后一个

删除中间几个
两个参数 删除包含第一个参数,不包含第二个参数


	list<Node>::iterator ite = ls.begin();
	ite++;
	
用begin	
	ls.erase(ite,--ls.end()); // 会删除ls的第二个带最后一个前一个,删除一个参数和最后一个参数中间的

  • 全部删除clear
	list<Node> ls;

	ls.push_front(Node(12, 'a'));
	ls.push_front(Node(13, 'b'));
	ls.push_front(Node(14, 'c'));
	ls.push_front(Node(15, 'd'));
	ls.push_front(Node(15, 'd'));
	ls.push_front(Node(16, 'e'));

	ls.clear();

参数相同的删除掉remove
remove需要先判断你输入的数据与所要对比中的数据是否相等。当判断两个结构体或者两个类是否相等的时候,不能直接判断需要。要在结构体或类中重新定义一个==的重载运算符。

struct Node
{
	int a;
	char c; // 0 

	Node(int d, char e)
	{
		a = d;
		c = e;
	}

重新定义一个==的重载运算符
	bool operator== (const Node& f)  // 参数要是const类型
	{
		if (f.a == this->a && f.c == this->c)
		{
			return true;
		}
		return false;
	}
};

然后再

list<Node> ls;

ls.push_front(Node(12, 'a'));
ls.push_front(Node(13, 'b'));
ls.push_front(Node(14, 'c'));
	
ls.remove(Node(18, 'c')); 

删除list中重复的元素 :unique()

修改

两个参数
用多个相同的值给list对象赋值,原来的数据都被覆盖掉

ls.assign(3, Node(2, 'c'));
swap两个list对象交换

将list1和list的内容交换

ls1.swap(ls);
reverse倒转list对象
ls.reverse();

sort()
默认从小到大排序
如果容器本身自带排序,那么使用的时候就可以不用选择排序算法
排序先要进行比较,但是某些结构体或者类的比较需要重载运算符。

struct Node
{
	int a;
	char c; // 0 

	Node(int d, char e)
	{
		a = d;
		c = e;
	}
	
重载一下小于号运算符
	bool operator< (const Node& f)
	{
		if (f.a < this->a)
		{
			return true;
		}

		return false;
	}
};

然后在调用排序

list<Node> ls;

ls.push_back(Node(16, 'e'));
ls.push_back(Node(15, 'd'));
ls.push_back(Node(15, 'd'));
	
ls.sort(); // 会按照node中第一个数据排序

从大到小的排序可以改变一下从在运算符的符号小于号改为大于号,也可以排序后在反转一下,建议改符号
ls.sort();
ls.reverse();
合并两个list对象

void merge( list &lst );
自动排序
重载小于号
两个链表必须有序
如果链表元素是升序的,就要用<号,return true
如果链表元素是降序的,就要用>号,return true

ls.merge(ls1);
拼接函数

拼接
void splice( iterator pos, list &lst );
void splice( iterator pos, list &lst, iterator del );
void splice( iterator pos, list &lst, iterator start, iterator end );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值