【C++】List 基本接口的使用

前边博客中已经介绍了c++ STL 中的 string 以及 vector 基本接口的使用方法并进行了接口的模拟实现,接下来让我们来学习 list 的基本接口使用方法吧~~

List 基本接口介绍

前言

List 是一个带头结点的双向循环链表,已知头节点 _head 可以找到它的前驱节点(尾节点)以及后继节点(首节点–第一个节点),但是寻找中间的某个节点信息时候就需要从 _head 位置开始进行遍历:

在这里插入图片描述

list 构造方法

本博客介绍的是 C++98 下的构造方法:
在这里插入图片描述

(1)构造一个空链表

list (const allocator_type& alloc = allocator_type());

(2)构造有 n 个值为 val 的链表

list (size_type n, const value_type& val = value_type(),
const allocator_type& alloc = allocator_type());

(3)区间构造方法

template < class InputIterator >
list (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());

(4)拷贝构造

list (const list& x);

为了便于后续的接口测试,我们来自定义一个打印函数:

template<class T>
void PrintMyList(const list<T>& L)
{
	for (auto e : L)
		cout << e << " ";
	cout << endl;
}

接下来看看如何进行使用这些构造接口:

void my_test0()
{
	list<int> L1;
	list<int> L2(5, 3);

	vector<int> v{ 1,2,3,4,5,6,7,8 };
	list<int> L3(v.begin(), v.end());

	list<int> L4(L3);
}

在这里插入图片描述

list 析构方法

在这里插入图片描述
在使用库中的接口信息,链表使用结束是会自动进行销毁操作的。

容量相关

在这里插入图片描述

在这里插入图片描述

元素获取

在这里插入图片描述
在这里插入图片描述

迭代器

在这里插入图片描述

(1)正向迭代器

回顾在 vector 中,我们提到迭代器是为了便于获取容器中间的所有元素,因此在正向迭代器中 begin() 指向的是第一个元素的位置,end() 指向的是最后一个有效元素的下一个空间的位置

而在 list 当中,由于 list 是带头双向循环链表,因此将 begin() 设在首节点的位置 ,end() 设在最后一个有效元素的下一个空间的位置,也就是头节点的位置:

在这里插入图片描述

(2)反向迭代器

与正向迭代器刚好相反:

反向迭代器
我们来测试一下遍历 list 链表:

在这里插入图片描述

元素的修改

在这里插入图片描述

(1)尾插尾删、头插头删接口测试

在这里插入图片描述

(2)任意位置插入接口测试

insert

在 pos 位置插入单个值为 val 的元素:

iterator insert (iterator position, const value_type& val);

1)insert 在第一个元素之前插入新元素:

在这里插入图片描述

从图中我们可以看出在链表的头部插入元素可以成功,并且打印链表信息也是可以的

回顾

在 vector 容器中我们提到了“迭代器失效”,是指由于插入元素或是删除元素导致容器底层空间发生变化而导致迭代器所指向的位置失效,那么在 list 中是否也会发生迭代器失效呢?我们可以打印迭代器所指向位置的元素来试试看:

在这里插入图片描述
从打印信息来看,在 pos 位置之前插入新的元素时,并未发生迭代器的失效

2)insert 在尾部插入新元素:

在这里插入图片描述

3)insert 在指定元素之前插入新元素:

在这里插入图片描述

在此段代码中我们使用到了查找算法,需要对 list 链表进行从头开始的遍历:

	int val=4;   //要进行查找的元素
	auto pos = L1.begin();
	while (pos != L1.end())
	{
		if (*pos == val)   //找到该元素位置
			break;
		++pos;
	}

假如代码中存在多处的查找操作,采用普通的遍历操作会使得代码效率极大地降低,并且会造成代码的冗余,因此在 C++ 库中给我们提供了一个全局的查找接口 find,可以在 vector 容器或是 list 链表中进行查找操作:

template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val);

因此上述查找我们直接可以使用一行代码来进行替换:

auto pos = find(L1.begin(), L1.end(), 4);

在这里插入图片描述

在 pos 位置插入 n 个值为 val 的元素:

void insert (iterator position, size_type n, const value_type& val);

在这里插入图片描述

在 pos 位置插入某个给定区间中的元素

template < class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);

在这里插入图片描述

(3)在任意位置删除接口测试

删除某个位置元素:

iterator erase (iterator position);

在这里插入图片描述
可以发现,删除元素时候导致了删除位置的迭代器失效了,但是后续的元素可以正常进行打印,在上一篇博客中我们指导在 vector 容器中插入或删除元素都会导致迭代器失效,并且操作(插入或删除)之后不能够获取到后续元素,而 list 只有在删除元素时候会导致迭代器的失效

为防止发生迭代器失效,我们需要将删除之后的元素位置进行返回即可避免:

在这里插入图片描述

删除区间中元素:

iterator erase (iterator first, iterator last);

在这里插入图片描述

(4)swap 交换接口测试

	list<int> L1{ 1,2,3,4,5,6 };
	list<int> L2{ 9,8,7,6,5 };
	L1.swap(L2);

在这里插入图片描述

(5)resize 接口测试

resize 修改有效元素个数,多余空间使用 val 来进行填充:

void resize (size_type n, value_type val = value_type());

在这里插入图片描述

(6)clear 接口测试

清空所有有效元素:

在这里插入图片描述

其他相关操作

在这里插入图片描述

(1)remove 移除所有值为 val 的元素

void remove (const value_type& val);

在这里插入图片描述

(2)remove_if 移除满足条件的元素

template < class Predicate>
void remove_if (Predicate pred);

在这里插入图片描述

(3)sort 对 list 中元素进行排序

sort 默认是按照升序进行排序的:
在这里插入图片描述

若想要指定排序方式,我们可以自定义一个函数:

//定义排序方式函数
bool My_Compare(int left, int right)
{
	//return left < right;   // 小于方式---------升序排序
	return left > right;   //大于方式----------降序排序
}

在这里插入图片描述

(4)merge 合并两个链表

默认方式进行合并

void merge (list& x);

在这里插入图片描述

当我们调用 merge 接口时候发现触发了异常,这主要是因为编译器不知道以何种方式对这两个链表进行合并,因此在进行链表合并操作之前我们要先对链表进行一个排序的操作

在这里插入图片描述

自定义合并链表的方式(降序为例)

template < class Compare>
void merge (list& x, Compare comp);

//定义排序方式函数
bool My_Compare(int left, int right)
{
	//return left < right;   // 小于方式---------升序排序
	return left > right;   //大于方式----------降序排序
}

在这里插入图片描述

(5)reverse 链表的逆置

直接调用接口即可:
在这里插入图片描述

有关于 list 库中接口的测试就到这里啦,小伙伴们一定要自己动手来测一测才能理解得更加深刻哦!

下一节我们来介绍有关于 list 相关接口的模拟实现哈!(提示:注意理解迭代器的使用内涵**)

敲黑板

多练多理解,多试错多调试才能够进步,加油吧!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值