list容器的基本概念及常用接口

list(链表)的基本概念

功能

将数据进行链式存储

链式存储是线性表的另一种表现形式。链表(list)是一种具体的实现形式。链表由一系列结点构成。结点由数据域和指针域构成。(具体请参考相关数据结构书籍)

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

双向循环链表内部实现原理

双向链表中的结点由结构体或类实现,内部有两个指针域和一个数据域。指针域分别为front和back。front指向前一个结点,rear指向当前结点的后一个结点。链表中第一个结点的front指针指向最后一个结点,最后一个结点的back指针指向第一个结点,从而在遍历时达到循环的效果。

双向循环链表的结构示意图为:

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

list优缺点分析

list的优点

1、采用动态存储分配,不会造成内存的浪费和溢出

2、链表执行插入和删除操作十分方便,时间开销小,不需要移动大量元素,只需修改指针即可

list的缺点

链表虽然插入和删除操作十分方便,但由于在实际内存中并非是连续存取,因此不能实现对数据的随机访问。且由于每个结点都需要用多余的空间存储指针域,因此对空间的耗费更高

list与vector的对比

1、list插入操作和删除操作并不会使原有list迭代器失效(只要不删除迭代器所指向的元素),而vector的迭代器在进行插入和删除操作后,迭代器会立即失效

2、STL中vector和list是两个最常被使用的容器,各有优缺点

list构造函数

注:list同样可以用push_back(尾插法)将数据插入到链表尾,同样支持用push_front(头插法)将数据插入到表头

list构造函数与其他几个STL常用容器类似,熟练掌握即可

list容器赋值与交换

作用:给list容器赋值以及交换list容器

eg:

#include<iostream>
using namespace std;
#include<list>
#include<string>
void printList(const list<int>&l)
{
	for (list<int>::const_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_front(10);//头插
	l.push_front(20);
	printList(l);
	list<int>L1 = l;//将l的值赋给L1
	printList(L1);
	list<int>L2(l.begin(), l.end());//将l区间范围内的元素赋给L2
	printList(L2);
	list<int>L3(5,100);//5个100
	printList(L3);
	L3.swap(l);//将L3与l的元素进行交换
	printList(l);
	printList(L3);
	system("pause");
	return 0;
}

list大小操作

作用:提供容器list指定大小/查询大小的操作

注:与其他容器的大小操作基本一致,熟练掌握即可

list容器的插入与删除

作用:对容器进行插入和元素删除

总结:

尾插--push_back   头插--push_front   尾删--pop_back     尾插--pop_front     插入--insert

删除--erase    移除--remove   清空--clear

eg:

#include<iostream>
using namespace std;
#include<list>
#include<string>
void printList(const list<int>&l)
{
	for (list<int>::const_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_front(10);//头插
	l.push_front(20);
	printList(l);//20 10 10 20
	l.pop_back();//尾删
	l.pop_front();//头删
	printList(l);//10 10
	l.insert(l.begin(), 100);//从链表头插入元素100
	printList(l);//100 10 10
	l.insert(l.end(), 5, 100);//在表尾插入5个100
	printList(l);//100 10 10 100 100 100 100 100
	l.erase(l.begin());//删除链表头的元素
	printList(l);// 10 10 100 100 100 100 100
	l.remove(100);//删除链表中所有数据为100的元素
	printList(l);//10 10
	l.clear();//清空链表
	printList(l);
	return 0;
}

list数据存取

可以通过front和back成员函数访问容器的首尾元素,若要遍历各个元素,可以用迭代器进行++的操作,从而遍历容器中所有元素。

注:链表不能随机存取,即list不能用下标/at访问容器中的元素

list反转和排序

作用:可以利用reverse逆置链表或将链表元素排列有序

函数原型:

reverse()--反转

(成员函数)sort()---排序

eg:

#include<iostream>
using namespace std;
#include<list>
#include<string>
void printList(const list<int>&l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << ' ';
	}
	cout << endl;
}
bool compare(int a,int b)
{
	return a > b;//当a>b时返回true,即不交换
}
int main()
{
	list<int>l;
	l.push_back(50);//尾插
	l.push_back(20);
	l.push_front(10);//头插
	l.push_front(30);
	printList(l);//30 10 50 20
	reverse(l.begin(),l.end());
	printList(l);//20 50 10 30
	//由于链表不能随机存取,因此不能使用全局函数sort(即只有空间上连续存储的容器才能使用),但list成员函数中提供了排序函数
	l.sort();//默认升序
	printList(l);//10 20 30 50
	l.sort(compare);//若想实现其他排序,则需要自己定义比较函数
	printList(l);//50 30 20 10
	return 0;
}

  • 37
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值