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

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

list的介绍


list本质是一个带头的双向循环链表

  • list是一种可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  • list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立结点当中,在结点中通过指针指向其前一个元素和后一个元素。
  • list与forward_list非常相似,最主要的不同在于forward_list是单链表,只能进行单方向迭代。
  • 与其他容器相比,list通常在任意位置进行插入、删除元素的执行效率更高。
  • list和forward_list最大的缺陷是不支持在任意位置的随机访问,其次,list还需要一些额外的空间,以保存每个结点之间的关联信息(对于存储的类型较小元素来说这可能是一个重要的因素)。

list常见接口的介绍


37aeada2d4cb4c57a3382c4b3e907829.png

list的构造函数


1.无参构造:list()

list<int> lt1;

2.用n个值为val的元素构造:list(size_type n,const value_type& val=value_type())

list<int> lt2(10,2);

3.拷贝构造:list(const list& lt)

list<int> lt3(lt2);

4. 用一段区间的元素构造list:list(Inputlterator first,Inputlterator last)

1. string s("hello world");
2. list<char> lt4(s.begin(),s.end());

实例演示

void PrintList(const list<int>& lt)
{
  list<int>::const_iterator it = lt.begin();
  while (it != lt.end())
  {
    cout << *it << " ";
    ++it;
  }
  cout << endl;
}
void test4()
{
  list<int> lt1;
  list<int> lt2(5, 2);
  list<int> lt3(lt2);
  list<int> lt4(lt2.begin(), lt2.end());
  cout << "lt1:";
  PrintList(lt1);
  cout << "It2:";
  PrintList(lt2);
  cout << "It3:";
  PrintList(lt3);
  cout << "It4:";
  PrintList(lt4);
}

代码运行结果如下:

image.png

list中迭代器


1.begin和end

image.png

通过begin函数可以得到容器中第一个元素的正向迭代器,通过end函数可以得到容器中最后一个元素的后一个位置的正向迭代器。

void test12()
{
  list<int> lt(10, 2);
  list<int>::iterator it = lt.begin();
  while (it != lt.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}

运行结果:

image.png

2.rbegin和rend

image.png

通过rbegin函数可以得到容器中最后一个元素的反向迭代器,通过rend函数可以得到容器中第一个元素的前一个位置的反向迭代器。

void test13()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.push_back(4);
  list<int>::reverse_iterator it = lt.rbegin();
  while (it != lt.rend())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}

运行结果

image.png

list的迭代器遍历


void TestList2()
{
  list<int>lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.push_front(0);
  lt.push_front(-1);
  lt.push_front(-2);
  list<int>::iterator it = lt.begin();
  while (it != lt.end())
  {
    cout << *it << " ";
    ++it;
  }
  cout << endl;
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  list<int>::reverse_iterator rit = lt.rbegin();
  while (rit != lt.rend())
  {
    cout << *rit << " ";
    ++rit;
  }
  cout << endl;
}

运行结果:

image.png

list的增删查改


1.push_front和pop_front

image.png

push_front函数用于头插一个数据,pop_front函数用于头删一个数据。

void test5()
{
  list<int> lt;
  lt.push_front(1);
  lt.push_front(2);
  lt.push_front(3);
  lt.push_front(4);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  lt.pop_front();
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
}

演示:

image.png

2.push_back和pop_back

image.png

push_back函数用于尾插一个数据,pop_back函数用于尾删一个数据。

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

演示

image.png

3.insert

image.png

list当中的insert函数支持三种插入方式:

  • 在指定迭代器位置插入一个数。
  • 在指定迭代器位置插入n个值为val的数。
  • 在指定迭代器位置插入一段迭代器区间(左闭右开)。
void test7()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  //1.在指定迭代器位置插入一个数
  list<int>::iterator pos = find(lt.begin(), lt.end(), 2);
  lt.insert(pos, 9);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  //2.在指定迭代器位置插入n个值为val的数
  pos = find(lt.begin(), lt.end(), 3);
  lt.insert(pos, 2, 8);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
}

演示:

image.png

4.erase

image.png

list当中的erase函数支持两种删除方式:

1.删除指定迭代器位置的元素。

2.删除指定迭代器区间的所有元素

void test8()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.push_back(4);
  lt.push_back(5);
  //删除指定迭代器位置的元素
  list<int>::iterator pos = find(lt.begin(), lt.end(), 2);
  lt.erase(pos);
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
  //删除指定迭代器区间的所有元素
  pos = find(lt.begin(), lt.end(), 4);
  lt.erase(pos, lt.end());
  for (auto e : lt)
  {
    cout << e << " ";
  }
  cout << endl;
}

演示

image.png

相关文章
|
8天前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
13 4
|
2月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
55 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
2月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
22 1
|
2月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
57 5
|
2月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
60 2
|
2月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(三)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
2月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(二)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
2月前
|
存储 编译器 C++
【C++】C++ STL 探索:List使用与背后底层逻辑(一)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
3月前
|
存储 JSON NoSQL
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
这篇文章是关于Redis基本数据结构的学习笔记,包括了String、Hash、Set、List和SortedSet的介绍和常用命令。文章解释了每种数据结构的特点和使用场景,并通过命令示例演示了如何在Redis中操作这些数据结构。此外,还提供了一些练习示例,帮助读者更好地理解和应用这些数据结构。
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
|
2月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
23 0