【C++】list的使用(下)

简介: 【C++】list的使用(下)

4. 数据修改

由于链表结构的特殊性,我们可以很方便的头插,尾插或者在任意位置插入,所以在这里库里面对于数据插入提供了很多种方式


1.数据插入

1. push_back:尾插

c4ff6151ad01522634132638604b7462.png


2. push_front:头插

9d8d9c737c2426989eb344844bbe26c8.png


3.insert:在任意位置插入删除

6e4fec604a7dab772931d1cddf1aac55.png

void Test_insert()
{
  vector<int> v(5, 888);
  list<int> lt;
  //尾插
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.push_back(4);
  lt.push_back(5);
  lt.push_back(6);
  auto it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  //头插
  lt.push_front(10);
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  //在任意位置插入
  auto it_push = ++lt.begin();//从第二个位置开始
  lt.insert(it_push, 30);//插入一个值
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  ++it_push;
  lt.insert(it_push, 5, 50);//插入n个值
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  ++it_push;
  lt.insert(it_push, v.begin(), v.end());//插入一个迭代器区间
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
}


240af744305ed8d89c59b7688d211f4d.png


2. 数据删除

与数据插入相对应的,数据删除也有三个

1. pop_back:尾删

f3de5b816274a3b01f30653223d2c50c.png


2.pop_front:头删

10f6d621146e980192e512cdafa52781.png


3.erase:任意位置删除

d315737d0195f6b4c0b6585ee6b70d24.png


void Test_erase()
{
  list<int> lt;
  for (int i = 0; i < 10; ++i)
  {
    lt.push_back(i);
  }
  auto it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  //头删
  lt.pop_front();
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  //尾删
  lt.pop_back();
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  //任意位置删除
  auto pos = ++lt.begin();
  pos = lt.erase(pos);//删除某一位置
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  auto start = ++pos;
  auto end = ++(++start);
  lt.erase(start, end);//删除一个迭代器区间
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
}

b8e8ff92d498662aa9600319d20ac06a.png


5.其他接口

除了上述的接口之外,还有一些我们之前在string和vector中没有见到的接口,下面我们来看看他们的用法

1. remove:删除list中指定值

4c1bcb45eb2c8a042d039132b22ab697.png

void Test_remove()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(2);
  lt.push_back(3);
  lt.push_back(4);
  lt.push_back(5);
  lt.push_back(6);
  lt.push_back(7);
  lt.push_back(8);
  auto it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  lt.remove(5);
  lt.remove(10);
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
}

39dadfc7716b1a609aa9d6832a7c7cca.png


可以看到,remove对于list中不存在的元素不会做任何操作

2. sort:排序list

4107be9707e30395b08615fd56c26cf1.png


看到这里肯定会有人有疑惑,sort算法库里面不是实现过吗?为什么又要重新在list里实现一下,我直接用算法库里面的不行吗?

✅答案是:不行,接下来看实验==》

8e81eeb344b8de8ea6a548962eabf847.png

可以看到,在编译的过程就已经报错了,这是因为库里面没有支持list迭代器类型的构造,为啥嘞?因为之前sort对容器内部的元素操作使用了+和-操作,但是list由于结构的限制,不支持迭代器的这个行为,所以对于list,要重新在库里面实现一个sort。


3. unique:删除list中的重复值

396dbe8769a04b11d007ba8a600615e0.png

这里注意一下,在使用unique之前要确保list是有序的,否则不能完成删除所有重复值的功能

void Test_Sort()
{
  list<int> lt;
  lt.push_back(1);
  lt.push_back(10);
  lt.push_back(9);
  lt.push_back(3);
  lt.push_back(6);
  lt.push_back(3);
  lt.push_back(7);
  lt.push_back(6);
  cout << "原list:";
  auto it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  lt.unique();
  cout << "尝试在乱序的情况下使用unique:";
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  lt.sort();
  cout << "排序list:";
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
  cout << "对有序的list使用unique:";
  lt.unique();
  it_out = lt.begin();
  while (it_out != lt.end())
  {
    cout << *it_out << " ";
    ++it_out;
  }
  cout << endl;
}

c4419961045a33dba05f8ad508f442bf.png

相关文章
|
2天前
|
调度 C++ 容器
【C++】手搓 list 容器
本文我们实现了STL库中重要的list 的模拟实现,其中最重要莫过于迭代器的封装类的书写,这是前所未有的操作(对于我来说,我是第一次使用这种结构)。通过list 的模拟实现也帮我们巩固了类与对象的知识,也强化了指针操作的思路。欢迎大家讨论分析。
12 1
|
5天前
|
存储 编译器 C++
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
5 0
|
18天前
|
存储 缓存 编译器
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
|
18天前
|
算法 C++ 容器
【C++进阶(四)】STL大法--list深度剖析&list迭代器问题探讨
【C++进阶(四)】STL大法--list深度剖析&list迭代器问题探讨
|
19天前
|
C++
c++的学习之路:16、list(3)
c++的学习之路:16、list(3)
12 0
|
19天前
|
C++
c++的学习之路:15、list(2)
c++的学习之路:15、list(2)
14 0
|
19天前
|
存储 C++ 容器
c++的学习之路:14、list(1)
c++的学习之路:14、list(1)
18 0
|
29天前
|
编译器 C++ 容器
【C++初阶】STL详解(八)List的模拟实现
【C++初阶】STL详解(八)List的模拟实现
39 0
|
29天前
|
存储 C++ 容器
【C++初阶】STL详解(五)List的介绍与使用
【C++初阶】STL详解(五)List的介绍与使用
32 0
|
1月前
|
存储 算法 编译器
【C++初阶】11. list的使用及模拟实现
【C++初阶】11. list的使用及模拟实现
52 3