我的编程空间,编程开发者的网络收藏夹
学习永远不晚

关于STL中list容器的一些总结

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

关于STL中list容器的一些总结

1.关于list容器

list是一种序列式容器。list容器完成的功能实际上和数据结构中的双向链表是极其相似的,list中的数据元素是通过链表指针串连成逻辑意义上的线性表,也就是list也具有链表的主要优点,即:在链表的任一位置进行元素的插入、删除操作都是快速的。list的实现大概是这样的:list的每个节点有三个域:前驱元素指针域、数据域和后继元素指针域。前驱元素指针域保存了前驱元素的首地址;数据域则是本节点的数据;后继元素指针域则保存了后继元素的首地址。其实,list和循环链表也有相似的地方,即:头节点的前驱元素指针域保存的是链表中尾元素的首地址,list的尾节点的后继元素指针域则保存了头节点的首地址,这样,list实际上就构成了一个双向循环链。由于list元素节点并不要求在一段连续的内存中,显然在list中是不支持快速随机存取的,因此对于迭代器,只能通过“++”或“--”操作将迭代器移动到后继/前驱节点元素处。而不能对迭代器进行+n或-n的操作,这点,是与vector等不同的地方。

我想把三个常用的序列式放在一起对比一下是有必要的:

vector :vector和built-in数组类似,拥有一段连续的内存空间,能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当插入较多的元素后,预留内存空间可能不够,需要重新申请一块足够大的内存并把原来的数据拷贝到新的内存空间。这些影响了vector的效率,但是实际上用的最多的还是vector容器,建议大多数时候使用vector效率一般是不错的。

list:list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。

deque:deque是一个double-ended queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率也差不多。

因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,具体可以遵循下面的原则:
1. 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2. 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3. 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。

2.list中常用的函数

2.1 list中的构造函数:

list() 声明一个空列表;

list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的

list(n,val) 声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的

list(n,val) 声明一个和上面一样的列表

list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素

--------------------------------------------------------------------------------

2.2 begin()和end():通过调用list容器的成员函数begin()得到一个指向容器起始位置的iterator,可以调用list容器的 end() 函数来得到list末端下一位置,相当于:int a[n]中的第n+1个位置a[n],实际上是不存在的,不能访问,经常作为循环结束判断结束条件使用。

--------------------------------------------------------------------------------

2.3 push_back() 和push_front():使用list的成员函数push_back和push_front插入一个元素到list中。其中push_back()从list的末端插入,而 push_front()实现的从list的头部插入。

--------------------------------------------------------------------------------

2.4 empty():利用empty() 判断list是否为空。

--------------------------------------------------------------------------------

2.5 resize(): 如果调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除,如果需要扩展那么调用默认构造函数T()将元素加到list末端。如果调用resize(n,val),则扩展元素要调用构造函数T(val)函数进行元素构造,其余部分相同。

--------------------------------------------------------------------------------

2.6 clear(): 清空list中的所有元素。

--------------------------------------------------------------------------------

2.7 front()和back(): 通过front()可以获得list容器中的头部元素,通过back()可以获得list容器的最后一个元素。但是有一点要注意,就是list中元素是空的时候,这时候调用front()和back()会发生什么呢?实际上会发生不能正常读取数据的情况,但是这并不报错,那我们编程序时就要注意了,个人觉得在使用之前最好先调用empty()函数判断list是否为空。

--------------------------------------------------------------------------------

2.8 pop_back和pop_front():通过删除最后一个元素,通过pop_front()删除第一个元素;序列必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉。

--------------------------------------------------------------------------------

2.9 assign():具体和vector中的操作类似,也是有两种情况,第一种是:l1.assign(n,val)将 l1中元素变为n个T(val)。第二种情况是:l1.assign(l2.begin(),l2.end())将l2中的从l2.begin()到l2.end()之间的数值赋值给l1。

--------------------------------------------------------------------------------

2.10 swap():交换两个链表(两个重载),一个是l1.swap(l2); 另外一个是swap(l1,l2),都可能完成连个链表的交换。

--------------------------------------------------------------------------------

2.11 reverse():通过reverse()完成list的逆置。

--------------------------------------------------------------------------------

2.12 merge():合并两个链表并使之默认升序(也可改),l1.merge(l2,greater<int>()); 调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序。其实默认是升序,greater<int>()可以省略,另外greater<int>()是可以变的,也可以不按升序排列。

看一下下面的程序:

复制代码 代码如下:

#include <iostream>
#include <list>

using namespace std;

int main()
{
    list<int> l1;
    list<int> l2(2,0);
    list<int>::iterator iter;
    l1.push_back(1);
    l1.push_back(2);
    l2.push_back(3);
    l1.merge(l2,greater<int>());//合并后升序排列,实际上默认就是升序
    for(iter = l1.begin() ; iter != l1.end() ; iter++)
    {
        cout<<*iter<<" ";
    }
    cout<<endl<<endl;
    if(l2.empty())
    {
        cout<<"l2 变为空 !!";
    }
    cout<<endl<<endl;
    return 0;
}


运行结果:

2.13 insert():在指定位置插入一个或多个元素(三个重载):

l1.insert(l1.begin(),100); 在l1的开始位置插入100。

l1.insert(l1.begin(),2,200); 在l1的开始位置插入2个100。

l1.insert(l1.begin(),l2.begin(),l2.end());在l1的开始位置插入l2的从开始到结束的所有位置的元素。

--------------------------------------------------------------------------------

2.14 erase():删除一个元素或一个区域的元素(两个重载)

l1.erase(l1.begin()); 将l1的第一个元素删除。

l1.erase(l1.begin(),l1.end()); 将l1的从begin()到end()之间的元素删除。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

关于STL中list容器的一些总结

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

关于STL中list容器的一些总结

list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载
2022-11-15

关于STL中vector容器的一些总结

vector作为STL提供的标准容器之一,是经常要使用的,有很重要的地位,并且使用起来也是灰常方便。vector又被称为向量,vector可以形象的描述为长度可以动态改变的数组,功能和数组较为相似
2022-11-15

关于STL中的map容器的一些总结

对于map的学习,或者说是对STL中的容器的学习,要知道每种容器的实现原理,每种适合适合解决什么问题的,才是关键
2022-11-15

关于C++中的友元函数的一些总结

以下是对C++中的友元函数进行了详细的总结介绍,需要的朋友可以过来参考下
2022-11-15

对于《关于使用Delphi XE10 进行android开发的一些总结》的补充

看了一篇《关于使用Delphi XE10 进行android开发的一些总结》有些想说的。 以下内容有复制原文,正常字体显示的是原文,黑体是我想说的。 我并不想讨论什么样的开发语言更优秀,只希望能以我自己的体会、总结的使用情况,说出我的感受
2022-06-06

一些Linux Shell中的权限相关知识总结

一个文件一经创建,就具有三种访问方式: 1) 读,可以显示该文件的内容。 2) 写,可以编辑或删除它。 3) 执行,如果该文件是一个s h e l l脚本或程序。 按照所针对的用户,文件的权限可分为三类: 1) 文件属主,创建该文件的用户。
2022-06-04

关于java中的循环结构的一些题目分享

1.计算1+2+3+…+99的和思路:余2等于0的是偶数,去除掉就可得到奇数public class Test1{public static void main(String [] args){//声明1到100奇数和的变量sumint sum = 0;for
关于java中的循环结构的一些题目分享
2017-07-17

Discuz教程之关于安装使用时的一些小细节问题的总结

首先先看一下安装教程https://www.jb51.net/cms/17055_2.html下面我们以问答的形式来说明: Q:請問如何實現版主跨版評分?A:后台》全局》用户权限》版主评分限制:否Q:如何设置限制评分数额?A:后台》用户》管
2022-06-12

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录