C++学习笔记(十六)——list(二)

简介: C++学习笔记(十六)——list

list的大小和头尾元素读取


1.size

image.png

size函数用于获取当前容器当中得元素个数.

void test11()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.push_back(4);
  cout << lt.size() << endl;//4
}

2.resize

image.png

resize的两种情况:

  • 当所给值大于当前的size时,将size扩大到该值,扩大的数据为第二个所给值,若未给出,则默认为容器所存储类型的默认构造函数所构造出来的值。
  • 当所给值小于当前的size时,将size缩小到该值。
void test17()
{
  list<int> lt(5, 3);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  lt.resize(7, 6);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  lt.resize(2);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
}

运行结果:

image.png

3.empty

image.png

empty函数用于判断当前容器是否为空。

1. void test16()
2. {
3.  list<int> lt;
4.  cout << lt.empty() << endl;//1
5. }

4.clear

image.png

clear函数用于清空容器,清空后容器的size为0。

void test15()
{
  list<int> lt(5, 2);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  cout << lt.size() << endl;
  lt.clear();
  cout << lt.size() << endl;
}

运行结果:

image.png

5.front和back

image.png

image.png

 front函数用于获取list容器当中的第一个元素,back函数用于获取list容器当中的最后一个元素。

void test14()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  cout << lt.front() << endl;
  cout << lt.back() << endl;
}

运行结果:

image.png

list的操作函数


1.sort

image.png

sort函数可以将容器当中的数据默认排为升序。

void test19()
{
  list<int> lt;
  lt.push_back(2);
  lt.push_back(5);
  lt.push_back(8);
  lt.push_back(10);
  lt.push_back(11);
  lt.push_back(7);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  lt.sort();
  for (auto e : lt)
  {
    cout << e << " ";
  }
}

运行结果

image.png

2.splice

image.png

splice函数用于两个list容器之间的拼接,其有三种拼接方式:

1.将整个容器拼接到另一个容器的指定迭代器位置。

2.将容器当中的某一个数据拼接到另一个容器的指定迭代器位置。

3.将容器指定迭代器区间的数据拼接到另一个容器的指定迭代器位置。

#include <iostream>
#include <list>
using namespace std;
int main()
{
  list<int> lt1(4, 2);
  list<int> lt2(4, 6);
  lt1.splice(lt1.begin(), lt2); //将容器lt2拼接到容器lt1的开头
  for (auto e : lt1)
  {
    cout << e << " ";
  }
  cout << endl; //6 6 6 6 2 2 2 2 
  list<int> lt3(4, 2);
  list<int> lt4(4, 6);
  lt3.splice(lt3.begin(), lt4, lt4.begin()); //将容器lt4的第一个数据拼接到容器lt3的开头
  for (auto e : lt3)
  {
    cout << e << " ";
  }
  cout << endl; //6 2 2 2 2 
  list<int> lt5(4, 2);
  list<int> lt6(4, 6);
  lt5.splice(lt5.begin(), lt6, lt6.begin(), lt6.end()); //将容器lt6的指定迭代器区间内的数据拼接到容器lt5的开头
  for (auto e : lt5)
  {
    cout << e << " ";
  }
  cout << endl; //6 6 6 6 2 2 2 2
  return 0;
}

注意: 容器当中被拼接到另一个容器的数据在原容器当中就不存在了。(实际上就是将链表当中的指定结点拼接到了另一个容器当中)

3.remove

image.png

remove函数用于删除容器当中特定值的元素。

#include <iostream>
#include <list>
using namespace std;
int main()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(4);
  lt.push_back(3);
  lt.push_back(3);
  lt.push_back(2);
  lt.push_back(2);
  lt.push_back(3);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl; //1 4 3 3 2 2 3
  lt.remove(3); //删除容器当中值为3的元素
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl; //1 4 2 2
  return 0;
}

4.reverse

image.png

reverse函数用于将容器当中元素的位置进行逆置。

void test21()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.reverse();
  for (auto e : lt)
  {
    cout << e << " ";
  }
}

运行结果:

image.png

5.assign

image.png

assign函数用于将新内容分配给容器,替换其当前内容,新内容的赋予方式有两种:

1.将n个值为val的数据分配给容器

2.将所给迭代器区间当中的内容分配给容器

void test20()
{
  list<char> lt(3, 'a');
  lt.assign(3, 'b');
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  string s("hello world");
  lt.assign(s.begin(), s.end());
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
}

运行结果:

image.png

6.swap

image.png

void test18()
{
  list<int> lt1(4, 2);
  list<int> lt2(4, 6);
  lt1.swap(lt2);
  for (auto e : lt1)
  {
    cout << e << " ";
  }
  cout << endl;
  for (auto e : lt2)
  {
    cout << e << " ";
  }
  cout << endl;
}

运行结果

image.png

list迭代器失效


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

两种情况测试

1.插入

void test9()
{
  int arr[] = { 1,2,3,4,5 };
  list<int> lt(arr, arr + sizeof(arr) / sizeof(arr[0]));
  list<int>::iterator it = lt.begin();
  lt.insert(it, 3);
  for (auto e : lt)
  {
    cout << e << " ";
  }
}

代码运行结果:

image.png

2.删除

void test10()
{
  int arr[] = { 1,2,3,4,5 };
  list<int> lt(arr, arr + sizeof(arr) / sizeof(arr[0]));
  list<int>::iterator it = lt.begin();
  while (it != lt.end())
  {
    lt.erase(it);
    ++it;
  }
}

代码运行结果:

image.png

致迭代器失效,删除数据会导致迭代器失效。相比vector容器,vector容器插入数据是会导致迭代器失效,因为vector涉及增容问题,而list却不存在增容问题,所以迭代器指向的位置是有效的。删除数据会导致迭代器指向的位置是无效的,所以迭代器会失效。

修改后的代码如下:

void test10()
{
  int arr[] = { 1,2,3,4,5 };
  list<int> lt(arr, arr + sizeof(arr) / sizeof(arr[0]));
  list<int>::iterator it = lt.begin();
  while (it != lt.end())
  {
    it = lt.erase(it);
  }
}
相关文章
|
5天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
15 1
|
17天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
33 7
|
26天前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
17 4
|
3月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
67 2
|
3月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
24 1
|
3月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
75 5
|
3月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
85 2
|
3月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(三)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
3月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(二)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
3月前
|
存储 编译器 C++
【C++】C++ STL 探索:List使用与背后底层逻辑(一)
【C++】C++ STL 探索:List使用与背后底层逻辑