C++list类

系列文章目录

C++入门

C++类和对象(上)

C++类和对象(中)

C++类和对象(下)

C/C++内存管理

C++string类

C++vector类



一、list是什么?

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素与后一个元素。
  3. list与forward_list非常相似,forward_list是单链表,只能单向迭代。
  4. 与其他序列式容器相比(vector,array,deque),list通常在任意位置进行插入和移除元素的效率要更好。
  5. 与其他序列式容器相比,list和forward_list的最大缺陷就是不支持随机访问,同时list还需要一些额外的空间,以保存每个结点的相关信息。

二、list的使用

1. list的构造

构造函数接口说明
list()构造空的list
lsit(size_type n, const value_type& val = value_type())构造一个有n个val元素的list
list(const list& x)拷贝构造函数
list(InputIterator first, InputIterator last)用迭代器区间构造list
void test()
{
	//空list
	list<int> l1;
	//包含10个整型1的list
	list<int> l2(10, 1);
	//用l2构造l3
	list<int> l3(l2);

	int arr[] = { 6,2,7,9 };
	//用迭代器区间构造
	list<int> l4(arr, arr + 4);
}

2.list iterator的使用

函数声明接口说明
begin + end返回第一个元素的迭代器 + 返回最后一个元素下一个位置的迭代器
rbegin + rend返回倒数第一个元素的迭代器 + 返回倒数最后一个元素下一个位置的迭代器

我们就把其当成一个带头结点的链表,begin()就是第一个元素的位置,end()就是头结点的位置。反之,rbegin()就是最后一个元素位置,rend()就是头结点的位置。

注意:

  1. begin()和end()为正向迭代器,对迭代器执行++操作,迭代器向后移动。
  2. rbegin()和rend()为反向迭代器,对迭代器执行++操作,迭代器向前移动。
void test2()
{
	//空list
	list<int> l1;
	//包含10个整型1的list
	list<int> l2(10, 1);
	//用l2构造l3
	list<int> l3(l2);

	int arr[] = { 6,2,7,9 };
	//用迭代器区间构造
	list<int> l4(arr, arr + 4);
	//正向遍历
	list<int>::iterator it = l4.begin();
	while (it != l4.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//反向遍历
	list<int>::reverse_iterator rit = l4.rbegin();
	while (rit != l4.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

3.list modifiers

函数声明接口说明
push_front在list首元素前插入元素
pop_front删除list中第一个元素
push_back在list尾部插入元素
pop_back删除list最后一个元素
insert在指定位置插入元素
erase在指定位置删除元素
swap交换两个list中元素
clear清空list中有效元素
void test3()
{
	int arr[] = { 1,5,2,7,8,3,9,6 };
	list<int> l1(arr, arr + sizeof(arr) / sizeof(arr[0]));
	//在list尾部插入4,在头部插入4
	l1.push_back(4);
	l1.push_front(4);
	PrintContainer(l1);

	//删除第一个结点和最后一个结点
	l1.pop_back();
	l1.pop_front();
	PrintContainer(l1);

	//获取链表中第二个结点
	auto pos = ++l1.begin();

	//在pos为之前插入10
	l1.insert(pos, 10);
	PrintContainer(l1);

	//在pos为之前插入3个0
	l1.insert(pos, 3, 0);
	PrintContainer(l1);

	//删除pos位置上的元素
	l1.erase(pos);
	PrintContainer(l1);

	//删除迭代器范围内元素
	l1.erase(l1.begin(), l1.end());
	PrintContainer(l1);

	list<int> l2(arr, arr + sizeof(arr) / sizeof(arr[0]));
	list<int> l3(3, 1);
	PrintContainer(l2);
	PrintContainer(l3);

	//交换l2,l3元素
	l2.swap(l3);
	PrintContainer(l2);
	PrintContainer(l3);

	//将l2中元素清空
	l2.clear();
	PrintContainer(l2);
	PrintContainer(l3);
}

三、list迭代器问题

在list中,迭代器失效即迭代器所指向的结点无效。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入是不会导致list的迭代器失效的,只有在删除的时候才会失效。并且失效的只是指向被删除结点的迭代器,其他的迭代器是不会受影响的。

void test4()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	list<int> l1(arr, arr + sizeof(arr) / sizeof(arr[0]));
	//找到list中3这个位置的迭代器
	list<int>::iterator pos = find(l1.begin(), l1.end(), 3);
	cout << *pos << endl;
	//删除这个迭代器所指向的元素,再打印
	l1.erase(pos);
	cout << *pos << endl;

}

让我们来看一下结果:
在这里插入图片描述
这里弹出了一个断言错误,因为删除这个元素后迭代器已经失效了,我们不能再去使用一个已经失效了的迭代器。


  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
C++ 中的 `list` 是一个双向链表容器,它可以动态地存储数据,并且可以在任意位置进行快速插入和删除操作,具有较好的性能表现。`list` 容器的头文件是 `#include <list>`。使用 `list` 需要注意以下几点: 1. `list` 是一个模板,需要指定存储元素的型,例如 `list<int>` 表示存储整型数据的链表。 2. `list` 中的元素是通过指针进行连接的,因此不能使用下标运算符 `[]` 来访问元素,可以使用迭代器来访问元素。 3. `list` 支持以下操作: - `push_back` / `push_front`:在链表尾部或头部插入元素; - `pop_back` / `pop_front`:删除链表尾部或头部的元素; - `insert`:在指定位置插入元素; - `erase`:删除指定位置的元素; - `size`:返回链表长度; - `clear`:清空链表中的所有元素。 一个简单的示例代码如下: ```c++ #include <iostream> #include <list> using namespace std; int main() { list<int> mylist; for (int i = 0; i < 5; i++) { mylist.push_back(i); } for (auto it = mylist.begin(); it != mylist.end(); it++) { cout << *it << " "; } cout << endl; mylist.pop_front(); mylist.insert(mylist.begin(), -1); mylist.erase(++mylist.begin()); for (auto x : mylist) { cout << x << " "; } cout << endl; return 0; } ``` 输出: ``` 0 1 2 3 4 -1 1 2 3 4 ``` 在这个示例中,我们首先创建了一个空的 `list` 对象 `mylist`,然后使用 `push_back` 在尾部插入了五个整数元素;接着使用迭代器遍历并输出链表中的元素;然后使用 `pop_front` 删除了链表头部的元素 `0`,使用 `insert` 在链表头部插入了一个元素 `-1`,使用 `erase` 删除了链表中的第二个元素 `1`;最后再次遍历并输出链表中的元素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值