一、前言

list容器,又称为双向链表容器,即该容器的底层是以双向链表的形式实现的,因此list容器中的元素可以分散存储在内存空间里,而不是必须存储在一整块连续的内存空间中。

list容器中各个元素的前后顺序是靠指针维系的,每个元素都有两个指针,分别指向它的前一个元素和后一个元素。第一个元素的前向指针总为 null,因为它前面没有元素;同样,尾部元素的后向指针也总为 null。

优点:可以在序列已知的任何位置快速插入或删除元素(时间复杂度为O(1))。并且在 list 容器中移动元素,也比其它容器的效率高。

缺点:不能通过下标访问元素,只能从容器中第一个元素或最后一个元素开始遍历容器,直到找到对应元素。

list 容器以模板类 list(T 为存储元素的类型)的形式在头文件中,并位于 std 命名空间中。使用时需包含头文件:

#include <list>
using namespace std;

二、初始化list容器

一共有5种方式创建list容器

  1. 创建空的list容器

    std::list<int> listInt;
  2. 创建一个包含10个元素,默认值为0的list容器

    std::list<int> listInt(10);
  3. 创建一个包含10个元素,初始值为5的list容器

    std::list<int> listInt(10, 5);
  4. 将以初始化的list容器进行拷贝创建新的list容器,须保证新旧容器存储的元素类型一致

    std::list<int> listInt2(listInt);
  5. 通过拷贝其他类型容器(或者普通数组)中指定区域内的元素,创建 list 容器
//拷贝普通数组,创建list容器
int a[] = { 1,2,3,4,5 };
std::list<int> listInt(a, a+5); //拷贝其它类型的容器,创建 list 容器
std::array<int, 5> arrInt{ 11,12,13,14,15 };
std::list<int> listInt(arrInt.begin()+2, arr.end());

1、成员函数

这里不列举迭代器、添加和删除等相关的函数。

函数功能

\[\begin{array}{|c|c|}
\hline \text { 函数 } & \text { 功能 } \\

\hline \text { empty() } &
\begin{array}{c}
\text {判断容器中是否有元素}\\
\text{若无元素,则返回 true;反之,返回 false }
\end{array} \\

\hline \text { end() } &
\text { 返回当前容器实际包含的元素个数 } \\

\hline \text {max_size() } &
\text { 返回容器所能包含元素个数的最大值,一般是 232-1 } \\

\hline \text { front() } &
\text {返回第一个元素的引用}\\

\hline \text { back()} &
\text {返回最后一个元素的引用}\\

\hline \text { assign()} &
\text {用新元素替换容器中原有内容}\\

\hline \text { swap(x,y) } &
\begin{array}{c}
\text {交换两个容器中的元素,}\\
\text{必须保证这两个容器中存储的元素类型是相同的}\\
\end{array}\\

\hline \text {resize()} &
\text {调整容器的大小}\\

\hline \text {splice()} &
\text {将一个 list 容器中的元素插入到另一个容器的指定位置}\\

\hline \text {merge()} &
\begin{array}{c}
\text {合并两个事先已排好序的 list 容器,}\\
\text{并且合并之后的 list 容器依然是有序的}\\
\end{array}\\

\hline \text {sort()} &
\begin{array}{c}
\text {通过更改容器中元素的位置,}\\
\text{将它们进行排序}\\
\end{array}\\

\hline \text {reverse()} &
\text {反转容器中元素的顺序}\\

\hline
\end{array}
\]

2、实例

1)创建list容器

  std::list<int> listInt;
listInt.push_back(31);
listInt.push_back(27);
listInt.push_back(29); std::cout << " listInt size: " << listInt.size() << std::endl; int i = 0;
std::list<int>::iterator listIter = listInt.begin();
for (; listIter != listInt.end(); listIter++)
{
std::cout << " listInt[" << i++ << "]=" << *listIter << std::endl;
} listInt.sort();
i = 0;
listIter = listInt.begin();
for (; listIter != listInt.end(); listIter++)
{
std::cout << " sort listInt[" << i++ << "]=" << *listIter << std::endl;
} int nFront = listInt.front();
int nBack = listInt.back();
std::cout << " listInt front: " << nFront << " back: " << nBack << std::endl; std::list<int> listInt1{ 14,25,99 };
listInt1.sort();
listInt.merge(listInt1);
i = 0;
listIter = listInt.begin();
for (; listIter != listInt.end(); listIter++)
{
std::cout << " merge listInt[" << i++ << "]=" << *listIter << std::endl;
}

结果如下:

3.迭代器

\[\begin{array}{|c|c|}
\hline \text { 函数 } & \text { 功能 } \\
\hline \text { begin() } & \begin{array}{l}
\text { 返回指向容器中第一个元素的双向迭代器(正向 } \\
\text { 迭代器) }
\end{array} \\
\hline \text { end }() & \begin{array}{l}
\text { 返回指向容器中最后一个元素所在位置的下一个 } \\
\text { 位置的双向迭代器。(正向迭代器) }
\end{array} \\
\hline \text { rbegin() } & \text { 返回指向最后一个元素的反向双向迭代器 } \\
\hline \text { rend() } & \begin{array}{l}
\text { 返回指向第一个元素所在位置前一个位置的反向 } \\
\text { 双向迭代器 }
\end{array} \\
\hline \text { cbegin() } & \begin{array}{l}
\text { 和 begin() 功能相同,只不过在其基础上,正向 } \\
\text { 迭代器增加了 const 属性,即不能用于修改元素 }
\end{array} \\
\hline \text { cend() } & \begin{array}{l}
\text { 和 end }(\text { ) 功能相同,只不过在其基础上,正向迭 } \\
\text { 代器增加了 const 属性,即不能用于修改元素 }
\end{array} \\
\hline \operatorname{crbegin}() & \begin{array}{l}
\text { 和 rbegin() 功能相同,只不过在其基础上,反向 } \\
\text { 迭代器增加了 const 属性,即不能用于修改元素 }
\end{array} \\
\hline \text { crend() } & \begin{array}{l}
\text { 和 rend() 功能相同,只不过在其基础上,反向迭 } \\
\text { 代器增加了 const 属性,即不能用于修改元素 }
\end{array} \\
\hline
\end{array}
\]

具体的功能不再说明,可参考array容器中的说明。list容器的迭代器和之前的array、vector等最大的不同在于:它的迭代器类型为双向迭代器,而不再是随机访问迭代器。

假如p1,p2都是双向迭代器,那么

支持++p1、 p1++、 p1--、 p1++、 *p1、 p1==p2 以及 p1!=p2;

不支持p1[i]、p1-=i、 p1+=i、 p1+i 、p1-i、p1<p2、 p1>p2、 p1<=p2、 p1>=p2。

1、实例

1)、遍历list容器元素

i = 0;

listIter = listInt.begin();

for (; listIter != listInt.end(); listIter++)

{

std::cout << " sort listInt[" << i++ << "]=" << *listIter << std::endl;

}

其他的函数功能和vector等类似,不再说明使用方法

注意点:

1、list 容器不支持随机访问,未提供下标操作符 [] 和 at() 成员函数,也没有提供 data() 成员函数

2、 front() 和 back() 成员函数,可以分别获得 list 容器中第一个元素和最后一个元素的引用形式,必要时还能修改其值

3、若希望访问list容器其他位置的元素,只能通过list容器的迭代器,也可以通过迭代器对指定元素的值进行修改

四、插入元素

\[\begin{array}{|c|c|}
\hline \text { 函数 } & \text { 功能 } \\
\hline \text { push_front() } & \text { 向 list 容器首个元素前添加新元素 } \\
\hline \text { push_back() } & \text { 向 list 容器最后一个元素后添加新元素 } \\
\hline \text { emplace_front() } & \text { 在容器首个元素前直接生成新的元素 } \\
\hline \text { emplace_back() } & \text { 在容器最后一个元素后直接生成新的元素 } \\
\hline \text { emplace() } & \text { 在容器的指定位置直接生成新的元素 } \\
\hline \text { insert() } & \text { 在指定位置插入新元素 } \\
\hline \text { splice() } & \begin{array}{l}
\text { 将其他 list 容器存储的多个元素添加到当前 list } \\
\text { 容器的指定位置处 }
\end{array} \\
\hline
\end{array}
\]

1、insert方法

\[\begin{array}{|l|l|}
\hline \text { 函数 } & \text { 功能 } \\

\hline \text { iterator insert(pos,elem) } &
\begin
\text { 在迭代器 pos 指定的位置之前插入一个新元素 elem,并返回表示新插入元素位置的迭代器 } \\

\hline \text { push_back() } & \text { 向 list 容器最后一个元素后添加新元素 } \\

\hline \text { emplace_front() } & \text { 在容器首个元素前直接生成新的元素 } \\

\hline \text { emplace_back() } & \text { 在容器最后一个元素后直接生成新的元素 } \\

\hline \text { emplace() } & \text { 在容器的指定位置直接生成新的元素 } \\

\hline \text { insert() } & \text { 在指定位置插入新元素 } \\

\hline \text { splice() } & \begin{array}{l}
\text { 将其他 list 容器存储的多个元素添加到当前 list } \\
\text { 容器的指定位置处 }
\end{array} \\
\hline
\end{array}
\]

C++ list容器的更多相关文章

  1. docker——容器安装tomcat

    写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...

  2. 网页提交中文到WEB容器的经历了些什么过程....

    先准备一个网页 <html><meta http-equiv="Content-Type" content="text/html; charset=gb ...

  3. [Spring]IoC容器之进击的注解

    先啰嗦两句: 第一次在博客园使用markdown编辑,感觉渲染样式差强人意,还是github的样式比较顺眼. 概述 Spring2.5 引入了注解. 于是,一个问题产生了:使用注解方式注入 JavaB ...

  4. 深入理解DIP、IoC、DI以及IoC容器

    摘要 面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.其中,OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.DI以及Ioc容器等概念.通过本文我们将一起学 ...

  5. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  6. JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题

    1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...

  7. docker4dotnet #2 容器化主机

    .NET 猿自从认识了小鲸鱼,感觉功力大增.上篇<docker4dotnet #1 前世今生&世界你好>中给大家介绍了如何在Windows上面配置Docker for Window ...

  8. 深入分析Spring 与 Spring MVC容器

    1 Spring MVC WEB配置 Spring Framework本身没有Web功能,Spring MVC使用WebApplicationContext类扩展ApplicationContext, ...

  9. Set容器--HashSet集合

    Set容器特点: ①   Set容器是一个不包含重复元素的Collection,并且最多包含一个null元素,它和List容器相反,Set容器不能保证其元素的顺序; ②   最常用的两个Set接口的实 ...

  10. 深入理解Spring--动手实现一个简单的SpringIOC容器

    接触Spring快半年了,前段时间刚用Spring4+S2H4做完了自己的毕设,但是很明显感觉对Spring尤其是IOC容器的实现原理理解的不到位,说白了,就是仅仅停留在会用的阶段,有一颗想读源码的心 ...

随机推荐

  1. HTML之CSS Animation 属性常用动画

    引入下面的样式表后 -webkit-animation: tada 1s ease 0.3s infinite both; -webkit-animation: name duration timin ...

  2. 从零玩转人脸识别验证-face

    title: 从零玩转人脸识别验证 date: 2022-05-15 21:05:52.974 updated: 2023-05-16 00:00:11.594 url: https://www.yb ...

  3. vscode快速配置汇编环境

    微机原理的课程需要,简单快速记录环境的搭建 找到并安装插件masm. MASM/TASM的汇编工具默认是tasm这样就无法在vscode终端进行debug,打开插件设置如下修改: 测试代码实现小写字母 ...

  4. curl使用小记(二)——远程下载一张图片

    目录 1. 概述 2. 实例 3. 参考 1. 概述 在之前的文章<curl使用小记(一)>中论述了命令行工具curl的基本使用.除此之外,curl还提供了能够直接供程序调用的模块库接口l ...

  5. LeetCode 图篇

    743. 网络延迟时间 有 N 个网络节点,标记为 1 到 N. 给定一个列表 times,表示信号经过有向边的传递时间. times[i] = (u, v, w),其中 u 是源节点,v 是目标节点 ...

  6. 掌数科技携手华为云GaussDB,助力金融科技创新,联合打造行业标杆

    本文分享自华为云社区<掌数科技携手华为云GaussDB,助力金融科技创新,联合打造行业标杆>,作者:GaussDB 数据库 . 近日,在华为开发者大会2023(Cloud)的"G ...

  7. 华为云MVP付健权:从机械工程师到AI开发者的华丽转身

    摘要:谁说AI开发难,看一个机械工程师是如何转型成为AI工程师的. 付健权,华为云MVP,企业上云导师.软通动力,售前解决方案经理,为制造业讲解华为云产品,为客户提供上云和云上解决方案.为企业提供大数 ...

  8. 从零开始学python | 使用Python映射,过滤和缩减函数:所有您需要知道的

    摘要:在本文中,您将学习Python中的三个令人印象深刻的函数,即map(),filter和reduce(). Python提供了许多预定义的内置函数,最终用户可以通过调用它们来使用它们.这些功能不仅 ...

  9. 1ms的时延,10Gbps速率…5G通信技术解读

    摘要:5G通信的关键技术有哪些呢?5G对于移动互联网场景和物联网场景又带来了哪些新的技术和变革? 本文分享自华为云社区<5G通信关键技术解读>,作者:Super.雯 . 5G作为目前最新一 ...

  10. 1个案例读懂——游戏产品如何用 A/B 测试做增长

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着国内游戏用户数量趋于饱和,中国游戏产业也从高速成长期逐渐转型,市场成熟度提升,竞争趋于精细化. 随着游戏出海以 ...