list 是顺序容器的一种。list 是一个双向链表。使用 list 需要包含头文件 list。双向链表的每个元素中都有一个指针指向后一个元素,也有一个指针指向前一个元素。

在 list 容器中,在已经定位到要增删元素的位置的情况下,增删元素能在常数时间内完成。如图2所示,在 ai 和 ai+1 之间插入一个元素,只需要修改 ai 和 ai+1 中的指针即可。


图1 :双向链表

图2:在双向链表中插入元素

list 容器不支持根据下标随机存取元素。

list 的构造函数和许多成员函数的用法都与 vector 类似。除了顺序容器都有的成员函数外,list 容器还独有如下表所示的成员函数(此表不包含全部成员函数,且有些函数的参数较为复杂,表中只列出函数名)。

list 的成员函数

成员函数或成员函数模板 作 用
void push_front(const T & val) 将 val 插入链表最前面
void pop_front() 删除链表最前面的元素
void sort() 将链表从小到大排序
void remove (const T & val) 删除和 val 相等的元素
remove_if 删除符合某种条件的元素
void unique() 删除所有和前一个元素相等的元素
void merge(list & x) 将链表 x 合并进来并清空 x。要求链表自身和 x 都是有序的
void splice(iterator i, list & x, iterator first, iterator last) 在位置 i 前面插入链表 x 中的区间 [first, last),并在链表 x 中删除该区间。链表自身和链表 x 可以是同一个链表,只要 i 不在 [first, last) 中即可

表中列出的成员函数有些是重载的,如 unique、merge、splice 成员函数都不止一个。

STL 中的算法 sort 可以用来对 vector 和 deque 排序,它需要随机访问迭代器的支持。因为 list 不支持随机访问迭代器,所以不能用算法 sort 对 list 容器排序。因此,list 容器引入了 sort 成员函数以完成排序。

list 的示例程序如下:

#include <list>  //使用 list 需要包含此头文件
#include <iostream>
#include <algorithm>  //使用STL中的算法需要包含此头文件
using namespace std;
class A {private: int n;
public:A(int n_) { n = n_; }friend bool operator < (const A & a1, const A & a2);friend bool operator == (const A & a1, const A & a2);friend ostream & operator << (ostream & o, const A & a);
};
bool operator < (const A & a1, const A & a2) {return a1.n < a2.n;
}
bool operator == (const A & a1, const A & a2) {return a1.n == a2.n;
}
ostream & operator << (ostream & o, const A & a) {o << a.n;return o;
}
template <class T>
void Print(T first, T last)
{for (; first != last; ++first)cout << *first << " ";cout << endl;
}
int main()
{A a[5] = { 1, 3, 2, 4, 2 };A b[7] = { 10, 30, 20, 30, 30, 40, 40 };list<A> lst1(a, a + 5), lst2(b, b + 7);lst1.sort();cout << "1)"; Print(lst1.begin(), lst1.end());  //输出:1)1 2 2 3 4lst1.remove(2);  //删除所有和A(2)相等的元素cout << "2)"; Print(lst1.begin(), lst1.end());  //输出:2)1 3 4lst2.pop_front();  //删除第一个元素cout << "3)"; Print(lst2.begin(), lst2.end());  //输出:3)30 20 30 30 40 40lst2.unique();  //删除所有和前一个元素相等的元素cout << "4)"; Print(lst2.begin(), lst2.end());  //输出:4)30 20 30 40lst2.sort();lst1.merge(lst2);  //合并 lst2 到 lst1 并清空 lst2cout << "5)"; Print(lst1.begin(), lst1.end());  //输出:5)1 3 4 20 30 30 40cout << "6)"; Print(lst2.begin(), lst2.end());  //lst2是空的,输出:6)lst1.reverse();  //将 lst1 前后颠倒cout << "7)"; Print(lst1.begin(), lst1.end());  //输出 7)40 30 30 20 4 3 1lst2.insert(lst2.begin(), a + 1, a + 4);  //在 lst2 中插入 3,2,4 三个元素list <A>::iterator p1, p2, p3;p1 = find(lst1.begin(), lst1.end(), 30);p2 = find(lst2.begin(), lst2.end(), 2);p3 = find(lst2.begin(), lst2.end(), 4);lst1.splice(p1, lst2, p2, p3);  //将[p2, p3)插入p1之前,并从 lst2 中删除[p2,p3)cout << "8)"; Print(lst1.begin(), lst1.end());  //输出:8)40 2 30 30 20 4 3 1cout << "9)"; Print(lst2.begin(), lst2.end());  //输出:9)3 4return 0;
}

用 list 解决约瑟夫问题。

约瑟夫问题是:有 n 只猴子,按顺时针方向围成一圈选大王(编号为 1~n),从第 1 号开始报数,一直数到 m,数到 m 的猴子退到圈外,剩下的猴子再接着从 1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王。编程求输入 n、m 后,输出最后猴王的编号。

输入数据:每行是用空格分开的两个整数,第一个是 n,第二个是 m(0<m, n<=1 000 000)。最后一行是:
0 0

输出要求:对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号。

输入样例:

6 2
12 4
8 3
0 0

输出样例:

5
1
7

示例程序如下:

#include <list>
#include <iostream>
using namespace std;
int main()
{list<int> monkeys;int n, m;while (true) {cin >> n >> m;if (n == 0 && m == 0)break;monkeys.clear();  //清空list容器for (int i = 1; i <= n; ++i)  //将猴子的编号放入listmonkeys.push_back(i);list<int>::iterator it = monkeys.begin();while (monkeys.size() > 1) { //只要还有不止一只猴子,就要找一只猴子让其出列for (int i = 1; i < m; ++i) { //报数++it;if (it == monkeys.end())it = monkeys.begin();}it = monkeys.erase(it); //删除元素后,迭代器失效,//要重新让迭代器指向被删元素的后面if (it == monkeys.end())it = monkeys.begin();}cout << monkeys.front() << endl; //front返回第一个元素的引用}return 0;
}

erase 成员函数返回被删除元素后面那个元素的迭代器。如果被删除的是最后一个元素,则返回 end()。

这个程序也可以用 vector 实现,但是执行速度要慢很多。因为 vector 的 erase 操作牵涉元素的移动,不能在常数时间内完成,所花费的时间和容器中的元素个数有关;而 list 的 erase 操作只是修改几个指针而已,可以在常数时间内完成。当 n 很大(数十万)时,两种写法在速度上会有明显区别。

C++ list,STL list相关推荐

  1. obj转stl_STL转STP的方法视频教程,OBJ格式转STP或者IGS开模具格式的过程,STL转STP软件介绍...

    STL转STP视频教程,OBJ格式转STP或者IGS开模具格式的方法过程 本文视频中详细演示STL格式转换成STEP格式的方法制作过程,3D文件格式转换过程,OBJ文件转实体STP或IGS可开模具格式 ...

  2. (P72)stl(一):泛型程序设计,什么是STL,STL六大组件及其关系

    文章目录 1.泛型程序设计 2.什么是STL 3.STL六大组件及其关系 1.泛型程序设计 泛型编程(generic programming) 类属编程 将程序写得尽可能通用 将算法从数据结构中抽象出 ...

  3. pythonocc基础使用:1.读取/写入brep,iges,step,stl文件

    总目录 >> PythonOCC入门进阶到实战(目前已更新入门篇.基础篇和进阶篇) 由作者实现的国产云端CAD www.yuntucad.com 对于cad系统的开发,读入外界的文件很重要 ...

  4. 【CodeForces-1041C】Coffee Break(贪心,STL,set二分维护,题意难,有坑,SJ题,构造)(知识点总结)

    题干: Recently Monocarp got a job. His working day lasts exactly mm minutes. During work, Monocarp wan ...

  5. 【HDU - 1968】【UVA - 12096】The SetStack Computer (模拟,集合求交集并集操作,STL实现)

    题干: Background from Wikipedia: 揝et theory is a branch of mathematics created principally by the Germ ...

  6. C++ vector,STL vector

    vector 是顺序容器的一种.vector 是可变长的动态数组,支持随机访问迭代器,所有 STL 算法都能对 vector 进行操作.要使用 vector,需要包含头文件 vector. 在 vec ...

  7. 【codevs1246】丑数,STL与取模大质数的好处

    丑数 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 对于一给定的素数集合 S = {p1, p2, -, ...

  8. 【CCCC】L2-019 悄悄关注 (25分),,模拟水题,STL大法好

    problem L2-019 悄悄关注 (25分) 新浪微博上有个"悄悄关注",一个用户悄悄关注的人,不出现在这个用户的关注列表上,但系统会推送其悄悄关注的人发表的微博给该用户.现 ...

  9. 助力PAT甲级/乙级取得满分的小技巧,STL容器

    STL容器的高级玩法 写在前面:本人于2020PAT甲级取得满分(见本人其他博客),在刷题过程中我有了很多自己的小经验和技巧,在这里分享给大家,祝大家刷题顺利,早日拿到免费的PAT徽章~~ 注意:这里 ...

最新文章

  1. 菜鸟学习.Net的感想!
  2. 新浪项目-------小知识点答疑解惑
  3. tcp connection setup的实现
  4. Python编程基础:第三十二节 文件写入Write a File
  5. ASP.NET MVC API 接口验证
  6. Windows Azure NotificationHub+Firebase Cloud Message 实现消息推动(付源码)
  7. elementui ts vant冲突_如何解决vue多个ui框架css冲突?
  8. OCP Java 自测
  9. Composer的Autoload源码实现2——注册与运行
  10. 设置iis支持wap服务
  11. c++ 指针_C/C++学习笔记——C提高:指针强化
  12. sql group by统计
  13. 抽象类、接口、内部类
  14. 微信分享wx.config配置时遇到invalid signature错误的解决办法
  15. 卷积神经网络(CNN)实现手写体识别
  16. JAVASCRIPT网页特效案例教程pdf
  17. Odoo相关资源(持续更新中)
  18. python金融大数据分析师工资待遇_国内数据分析待遇如何?
  19. 顶刊实证复现:排污权交易机制是否提高了企业全要素生产率 (思路梳理+全数据源+python代码)
  20. Qt小游戏教程之贪吃蛇(带源码)

热门文章

  1. eclipse不进入断点_Eclipse 调试中不支持运行到断点问题
  2. MyEclipse 2015优化技巧
  3. 幼儿课外活动游戏_泰国清迈大小学校介绍 --【Little Star小星星幼儿园】
  4. 深入学习二叉树(二) 线索二叉树
  5. mysql++多版本安装_MySQL多版本多实例安装启动
  6. java开发利器 源码_Java开发的利器: 反编译工具 JD-GUI
  7. java内部类为什么使用很少_java内部类有什么好处?为什么需要内部类?
  8. mysql主从报错_Mysql主从报错锦集
  9. 的安装方法_显卡安装方法
  10. MySQL 基础 ———— 流程控制结构