一篇文章让你轻松理解C++中vector和list区别

目录
  • 一张表格让你理解vector和list区别
  • 例子
  • 总结

一张表格让你理解vector和list区别

区别 vector list
数据结构: 顺序表(动态数组) 环形双向链表
物理空间: 连续的 非连续的
内存消耗:
大小可变: 可变-动态数组 可变-通过指针
随机存储: 支持(vector 重载了[]) 不支持(因为非连续)
优势: 支持随机存储 任意节点高效的插入、删除等操作
劣势: 插入和删除进行内存拷贝工作 不支持随机存取

数据结构对比图:

那我们怎样选择使用vector和list呢?

在选择该用哪种数据结构的时候,应该遵循这样的原则:

1. 如果只关心随机存取,不在乎插入和删除 ,那么就要考虑vector

2. 如果只关心插入删除,不在意随机存取, 那么就要考虑list

例子

处理大量数据时,数据相对固定,不关心排序和中间值插入和删除,只是进行查询和筛选时,选vector。

处理顺序发生改变的数据时,数据变化,比如排行榜需要进行换位,插入删除等操作,此时选择list。

由于list和vector上面的这些区别,因此list::iterator与vector::iterator也有一些不同。请看下面的例子:

        #include <iostream>
        #include <vector>
        #include <list>
        using namespace std;

        int main( void )
        {
                vector<int> v;
                list<int> l;

                for (int i=0; i<8; i++)     //往v和l中分别添加元素
                {
                        v.push_back(i);
                        l.push_back(i);
                }

                cout << "v[2] = " << v[2] << endl;
                //cout << "l[2] = " << l[2] << endl;       //编译错误,list没有重载[]
                cout << (v.begin() < v.end()) << endl;
                //cout << (l.begin() < l.end()) << endl;   //编译错误,list::iterator没有重载<或>
                cout << *(v.begin() + 1) << endl;

                vector<int>::iterator itv = v.begin();
                list<int>::iterator itl = l.begin();
                itv = itv + 2;
                //itl = itl + 2;                  //编译错误,list::iterator没有重载+
                itl++;itl++;                    //list::iterator中重载了++,只能使用++进行迭代访问。
                cout << *itv << endl;
                cout << *itl << endl;

                return 0;
        }

由于vector拥有一段连续的内存空间,能非常好的支持随机存取,因此vector<int>::iterator支持“+”、“+=”、“<”等操作符。

而list的内存空间可以是不连续,它不支持随机访问,因此list<int>::iterator则不支持“+”、“+=”、“<”等操作符运算,因此代码20、26行会有编译错误。只能使用“++”进行迭代,例如代码27行,使用两次itl++来移动itl。还有list也不支持[]运算符,因此代码18行出现编译错误。

总之,如果需要高效的随即存取,而不在乎插入和删除的效率,使用vector;如果需要大量的插入和删除,而不关心随即存取,则应使用list。

答案:

vector拥有一段连续的内存空间,因此支持随机存取,如果需要高效的随即存取,而不在乎插入和删除的效率,使用vector。

list拥有一段不连续的内存空间,因此支持随机存取,如果需要大量的插入和删除,而不关心随即存取,则应使用list。

总结

到此这篇关于C++中vector和list区别的文章就介绍到这了,更多相关C++中vector和list区别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c++容器list、vector、map、set区别与用法详解

    c++容器list.vector.map.set区别 list 封装链表,以链表形式实现,不支持[]运算符. 对随机访问的速度很慢(需要遍历整个链表),插入数据很快(不需要拷贝和移动数据,只需改变指针的指向). 新添加的元素,list可以任意加入. vector 封装数组,使用连续内存存储,支持[]运算符. 对随机访问的速度很快,对头插元素速度很慢,尾插元素速度很快 新添加的元素,vector有一套算法. map 采用平衡检索二叉树:红黑树 存储结构为键值对<key,value> set 采用

  • 一篇文章让你轻松理解C++中vector和list区别

    目录 一张表格让你理解vector和list区别 例子 总结 一张表格让你理解vector和list区别 区别 vector list 数据结构: 顺序表(动态数组) 环形双向链表 物理空间: 连续的 非连续的 内存消耗: 少 多 大小可变: 可变-动态数组 可变-通过指针 随机存储: 支持(vector 重载了[]) 不支持(因为非连续) 优势: 支持随机存储 任意节点高效的插入.删除等操作 劣势: 插入和删除进行内存拷贝工作 不支持随机存取 数据结构对比图: 那我们怎样选择使用vector和

  • 一篇文章带你搞定SpringBoot中的热部署devtools方法

    一.前期配置 创建项目时,需要加入 DevTools 依赖 二.测试使用 (1)建立 HelloController @RestController public class HelloController { @GetMapping("/hello") public String hello(){ return "hello devtools"; } } 对其进行修改:然后不用重新运行,重新构建即可:只加载变化的类 三.热部署的原理 Spring Boot 中热部

  • 一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃

    由于 Ubuntu 中的汉字输入实在是太不友好了,所以装了个 搜狗输入法,好不容易把 搜狗输入法装好,本以为可以开开心心的搞代码了,然而... pycharm 一打开,就崩溃,关不掉,进程杀死还是不行,只能关机重启. 本以为 pycharm 出现了问题,又重装了两遍,还是不行. 最终发现竟然是搜狗输入法以及 fcitx 输入法的锅 唉,只能老老实实的把 fctix 和搜狗输入法卸载了: (1)Ubuntu 软件里卸载 fctix,然后将键盘输入法系统改成 IBus (2)卸载搜狗输入法 先查找软

  • 一篇文章让你轻松记住js的隐式转化

    目录 前言 一.包装类 Boolean() 扩展 Number() 引用类型转换Number 原始类型转Number 还有这些混淆点是需要注意的: 扩展 String() Object.prototype.toString Array.prototype.toString 二.隐式转化触发规则 布尔的隐式转化 number的隐式转化 隐式转化最难的情况 三.特殊情况 四.工作不要使用 总结 前言 之前写过一篇文章[[js让人诟病的这些feature]]中提出过一个疑问. 这个问题一开始我想简单了

  • 一篇文章让你看懂IOS中的block为何再也不需要WeakSelf弱引用

    前言: 最近都在折腾Sagit架框的内存释放的问题,所以对这一块有些心得. 对于新手,学到的文章都在教你用:typeof(self) __weak weakSelf = self. 对于老手,可能早习惯了到处了WeakSelf了. 这次,就来学学,如何不用WeakSelf. 1:从引用计数器开始: 这里先设计一个TableBlock类: @interface BlockTable : NSObject typedef void (^AddCellBlock)(); @property (nona

  • 一篇文章带你轻松了解C# Lock关键字

    相信绝大多数.NET玩家和我一样,常常使用Timer这个对象,而在WPF中使用DispatcherTimer的人也是很多,DispatcherTimer是在UI线程跑的.我们的程序中大多数都会充斥很多Timer,可以理解它是一个线程,它继承自 System.Windows.Threading . 程序中也许会有一些静态变量或是单例模式的对象来让不同的页面进行交互,但也就是这样让每个线程之间打架提供了基础.因为资源是单独的,就像是脚踩两只船的人,必定会翻车.例如一个List集合,你在一个线程中对它

  • 一篇文章带你详细了解python中一些好用的库

    目录 时间库-arrow 使用背景 安装arrow arrow使用 游标卡尺shift 获取arrow对象 arrow的类型转换和时区修改 总结 时间库-arrow 使用背景 日期时间处理在实际应用场景中无处不在,所以这也成了编程语言中必不可少的模块,Python 也不例外.但是,你知道在Python中有多少个相关的模块吗?datetime.time.calendar. dateutil. pytz 等等. 你知道有多少种数据类型吗?date.time.datetime.tzinfo.timed

  • 轻松理解Python 中的 descriptor

    定义 通常,一个 descriptor 是具有"绑定行为"的对象属性.所绑定行为可通过 descriptor 协议被自定义的 __get__() , __set__() 和 __delete__() 方法重写.如果一个对象的上述三个方法任意一个被重写,则就可被称为 descriptor. 属性的默认操作是从对象字典中获取.设置和删除一个属性.例如,a.x 有一个查找链,先 a.__dict__['x'] ,若没有则 type(a).__dict__['x'] ,若没有增往上查找父类直到

  • 一篇文章带你深入理解JVM虚拟机读书笔记--锁优化

    目录 1. Java语言中的线程安全 1.1 不可变 1.2 绝对线程安全 1.3 相对线程安全 1.4 线程兼容 1.5 线程对立 2. 线程安全的实现方法 2.1 互斥同步 3. 锁优化 3.1 自旋锁与自适应自旋 3.2 锁消除 3.3 锁粗化 3.4 轻量级锁 3.5 偏向锁 总结 1. Java语言中的线程安全 按照线程安全的"安全程度"由强至弱来排序,可以将Java语言中各种操作共享的数据分为以下五类:不可变.绝对线程安全.相对线程安全.线程兼容和线程对立. 1.1 不可变

  • 一篇文章带你实现C语言中常用库函数的模拟

    目录 前言 函数介绍 strlen(求字符串长度) strcpy(字符串拷贝) strcat(字符串追加) strcmp(字符串比较) strstr(找子字符串) memcpy(内存拷贝) memmove(内存移动) 总结 前言 C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中. 字符串常量适用于那些对它不做修改的字符串函数. 函数介绍 strlen(求字符串长度) size_t strlen ( const char * str

随机推荐