顺序容器——list

本文详细介绍了C++ STL中的list容器,它是一个双向循环链表,优点在于插入和删除元素的时间复杂度为O(1)。文章列举了list的节点结构、常用操作函数,包括插入、删除、遍历、反转、合并等,并提供了相关示例,帮助读者深入理解list的使用。

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

list相较于vector的连续线性空间,list就显得复杂许多,它的好处是每次插入或删除一个元素,就配置或释放一个空间。因此,list对于空间的利用有绝对的精准,一点也不浪费。而且,对于任何位置的元素的插入或删除,它的时间复杂度都为O(1)。

list容器的底层实际上是一个双向循环链表。

list本身和list的节点的结构是不同的,需要分开设计

  • list的节点定义:
template<class T>
struct list_node
{
	typedef void* void  void_pointet;
	void_pointet prev; //指向前驱节点的指针
	void_pointet next; //指向后继节点的指针
	T data;
}
  • list中常用的操作函数

list() 声明一个空列表;

list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的

list(n,val) 声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的

list(n,val) 声明一个和上面一样的列表

list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素

begin():得到一个指向容器起始位置的iterator

end():得到list末端下一位置,相当于:int a[n]中的第n+1个位置a[n],实际上是不存在的,不能访问,经常作为循环结束判断结束条件使用。

push_back() 和push_front():使用list的成员函数push_back和push_front插入一个元素到list中。其中push_back()从list的末端插入,而 push_front()实现的从list的头部插入。

empty():利用empty() 判断list是否为空。

remove(value);移除值为value的所有元素

unique();移除数值相同的连续元素,剩一个

splice(value,list);将list接到值为value的元素之前 

resize(): resize(n);将list的长度改为只容纳n个元素,超出的元素将被删除如果需要扩展那么调用默认构造函数T()将元素加到list末端。
            resize(n,val):则扩展元素要调用构造函数T(val)函数进行元素构造,其余部分相同。

clear(): 清空list中的所有元素。

front():通过front()可以获得list容器中的头部元素

empty()函数判断list是否为空。

back():获得list容器的最后一个元素

pop_back和pop_front():通过删除最后一个元素,通过pop_front()删除第一个元素;序列必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉。

assign():具体和vector中的操作类似,也是有两种情况,第一种是:l1.assign(n,val)将 l1中元素变为n个T(val)。

第二种情况是:l1.assign(l2.begin(),l2.end())将l2中的从l2.begin()到l2.end()之间的数值赋值给l1。

swap():交换两个链表(两个重载),一个是l1.swap(l2); 另外一个是swap(l1,l2),都可能完成连个链表的交换。

reverse():通过reverse()完成list的逆置。

merge():合并两个链表并使之默认升序(也可改),l1.merge(l2,greater()); 调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序。其实默认是升序,greater()可以省略,另外greater()是可以变的,也可以不按升序排列。

insert():在指定位置插入一个或多个元素(三个重载):

insert(l1.begin(),100); 在l1的开始位置插入100。

insert(l1.begin(),2,200); 在l1的开始位置插入2个100。

insert(l1.begin(),l2.begin(),l2.end());在l1的开始位置插入l2的从开始到结束的所有位置的元素。

erase():删除一个元素或一个区域的元素(两个重载)

erase(l1.begin()); 将l1的第一个元素删除。

erase(l1.begin(),l1.end()); 将l1的从begin()到end()之间的元素删除。

  • list容器的使用‘

#include<list>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	//int i;
	list<int> ilist;
	cout<<"size="<<ilist.size()<<endl;
	ilist.push_back(0);
	ilist.push_back(1);
	ilist.push_back(2);
	ilist.push_back(3);
	ilist.push_back(4);
	cout<<"size="<<ilist.size()<<endl;
	list<int>::iterator ite;
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;

	ite=find(ilist.begin(),ilist.end(),3);
	if(*ite!=0)
		ilist.insert(ite,99);
	cout<<"size="<<ilist.size()<<endl;
	cout<<*ite<<endl;
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
	ite=find(ilist.begin(),ilist.end(),1);
	if(*ite!=0)
		cout<<*(ilist.erase(ite))<<endl;
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
	int ar[5]={3,4,6,7,8};
	list<int>list2(ar,ar+5);
	ite=find(ilist.begin(),ilist.end(),99);
	if(*ite!=0)
		ilist.splice(ite,list2);
		cout<<"size="<<ilist.size()<<endl;
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
	ilist.reverse();//将链表逆置
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
	ilist.sort();//排序
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
	ilist.remove(3);//删除所有值为3的元素
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
	ilist.unique();//删除连续一样的元素直至剩一个
	for(ite=ilist.begin();ite!=ilist.end();++ite)
		cout<<*ite<<" ";
	cout<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值