1、vector

向量 相当于一个数组

在内存中分配一块连续的内容空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数返回的大小,当超过此分配的空间时,再整体重新分配一块内存存储,这给人以vector为一个连续内存的感觉。通常此默认的内存分配能完成大部分情况下的存储。

优点

(1)不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数字进行动态操作。

(2)随机访问方便,即支持[ ]操作符和vector.at()

(3)节省空间。

缺点

(1)在内部进行插入删除操作效率低。

(2)只能在vector的最后进行push和pop,不能再vector的头进行push和pop。

(3)当动态添加的数据超过vector默认分配的大小时,要进行整体的重新分配、拷贝与释放

2、list

双向链表

每一个结点都包括一个信息块Info、一个前驱指针Pre、一个后驱指针Post。可以不分配必须的内存大小,方便地进行添加和删除操作。使用的是非连续的内存空间进行存储。

优点

(1)不使用连续内存完成动态操作。

(2)在内部方便的进行插入和删除操作。

(3)可在两端进行push、pop

缺点

(1)不能进行内部的随机访问,即不支持[ ]操作符和vector.at()

(2)相对于vector占用内存多

3、deque

双端队列 double-end queue

deque是在功能上合并了vector和list

优点

(1)随机访问方便,即支持[ ]操作符和vector.at()

(2)可在内部方便的进行插入和删除操作

(3)可在两端进行push、pop

缺点

(1)占用内存多

使用区别

1、如果你需要高效地随机存取,而不在乎插入和删除的效率,使用vector

2、如果你需要大量地插入和删除,而不关心随机存取,则应使用list

3、如果你需要随机存取,而且关心两端数据的插入和删除,则应使用deque

C++ STL中vector容器的用法

vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。为了可以使用vector,必须在你的头文件中包含下面的代码:

#include<vector>

vector属于std命名域,因此需要通过命名限定,如下完成你的代码:

using std::vector;
vector<int> v;

或者连在一起,使用全名:

std::vector<int> v;

建议使用全局的命名域方式:

using namespace std;

1、vector的声明

vector<ElemType> c;//创建一个空的vector

vector<ElemType> c1(c2);//创建一个vector c1,并用c2去初始化c1

vector<ElemType> c(n);//创建一个含有n个ElemType类型数据的vector

vector<ElemType> c(n,elem);//创建一个含有n个ElemType类型数据的vector,并全部初始化为elem
c.~vector<ElemType>();//销毁所有数据,释放资源

2、vector容器中常用的函数。(c为一个容器对象)


c.push_back(elem);   在容器最后位置添加一个元素elem

c.pop_back();            删除容器最后位置处的元素

c.at(index);                返回指定index位置处的元素

c.begin();                   返回指向容器最开始位置数据的指针

c.end();                      返回指向容器最后一个数据单元的指针+1

c.front();                     返回容器最开始单元数据的引用

c.back();                     返回容器最后一个数据的引用

c.max_size();              返回容器的最大容量

c.size();                      返回当前容器中实际存放元素的个数

c.capacity();               同c.size()

c.resize();                   重新设置vector的容量

c.reserve();                同c.resize()

c.erase(p);               删除指针p指向位置的数据,返回下指向下一个数据位置的指针(迭代器)

c.erase(begin,end)     删除begin,end区间的数据,返回指向下一个数据位置的指针(迭代器)

c.clear();                    清除所有数据

c.rbegin();                  将vector反转后的开始指针返回(其实就是原来的end-1)

c.rend();                     将vector反转后的结束指针返回(其实就是原来的begin-1)

c.empty();                   判断容器是否为空,若为空返回true,否则返回false

c1.swap(c2);               交换两个容器中的数据

c.insert(p,elem);          在指针p指向的位置插入数据elem,返回指向elem位置的指针

c.insert(p,n,elem);      在位置p插入n个elem数据,无返回值

c.insert(p,begin,end) 在位置p插入在区间[begin,end)的数据,无返回值


C++ STL中List的用法

1、常用函数


assign()                       给list赋值 
back()                         返回最后一个元素 
begin()                        返回指向第一个元素的迭代器 
clear()                         删除所有元素 
empty()                       如果list是空的则返回true 
end()                           返回末尾的迭代器 
erase()                        删除一个元素 
front()                          返回第一个元素 
get_allocator()            返回list的配置器 
insert()                        插入一个元素到list中 
max_size()                  返回list能容纳的最大元素数量 
merge()                       合并两个list 
pop_back()                  删除最后一个元素 
pop_front()                  删除第一个元素 
push_back()                在list的末尾添加一个元素 
push_front()                在list的头部添加一个元素 
rbegin()                       返回指向第一个元素的逆向迭代器 
remove()                     从list删除元素 
remove_if()                 按指定条件删除元素 
rend()                         指向list末尾的逆向迭代器 
resize()                       改变list的大小 
reverse()                    把list的元素倒转 
size()                          返回list中的元素个数 
sort()                          给list排序 
splice()                       合并两个list 
swap()                        交换两个list 
unique()                      删除list中重复的元素


2、实例

实例一:

/**
* File name: main.cpp
* Date: 2017.10.12
* Description:Example of using List
*/ #include <iostream>
#include <list>
#include <numeric>
#include <algorithm>
using namespace std; //创建一个list容器的实例LISTINT
typedef list<int> LISTINT;
//创建一个list容器的实例LISTCHAR
typedef list<char> LISTCHAR; int main()
{
//用list容器处理整型数据
LISTINT listOne;
//声明i为迭代器
LISTINT::iterator i; //从前面向listOne容器中添加数据
listOne.push_front();
listOne.push_front(); //从后面向listOne容器中添加数据
listOne.push_back();
listOne.push_back(); //从前向后显示listOne中的数据
cout << "listOne.begin() --- listOne.end():" << endl;
for (i = listOne.begin(); i != listOne.end(); ++i)
cout << *i << " ";
cout << endl; //从后向前显示listOne中的数据
LISTINT::reverse_iterator ir;
cout << "listOne.rbegin() --- listOne.rend():" << endl;
for (ir = listOne.rbegin(); ir != listOne.rend(); ir++)
cout << *ir << " ";
cout << endl; //使用STL的accumulate(累加)算法
int result = accumulate(listOne.begin(), listOne.end(), );
cout << "Sum=" << result << endl;
cout << "-------------------------" << endl; //-----------------------------
//用list容器处理字符型数据
//----------------------------- //用LISTCHAR创建一个名为listTwo的list对象
LISTCHAR listTwo;
//声明j为迭代器
LISTCHAR::iterator j; //从前面向listTwo容器中添加数据
listTwo.push_front('B');
listTwo.push_front('A'); //从后面向listTwo容器中添加数据
listTwo.push_back('x');
listTwo.push_back('y'); //从前向后显示listTwo中的数据
cout << "listTwo.begin() --- listTwo.end():" << endl;
for (j = listTwo.begin(); j != listTwo.end(); j++)
cout << *j << " ";
cout << endl; //使用STL的max_element算法求listTwo中的最大元素并显示
j = max_element(listTwo.begin(), listTwo.end());
cout << "The maximum element in listTwo is: " << *j << endl;
return ; }

输出结果:

实例二:

//实例二
#include <iostream>
#include <list> using namespace std;
typedef list<int> INTLIST; //从前向后显示list队列的全部元素
void put_list(INTLIST list, char *name)
{
INTLIST::iterator plist; cout << "The contents of " << name << " : ";
for (plist = list.begin(); plist != list.end(); plist++)
cout << *plist << " ";
cout << endl;
} //测试list容器的功能
int main(void)
{
//list1对象初始为空
INTLIST list1;
//list2对象最初有10个值为6的元素
INTLIST list2(, ); //声明一个名为i的双向迭代器
INTLIST::iterator i; //从前向后显示各list对象的元素
put_list(list1, "list1");
put_list(list2, "list2"); //从list1序列后面添加两个元素
list1.push_back();
list1.push_back();
cout << "list1.push_back(2) and list1.push_back(4):" << endl;
put_list(list1, "list1"); //从list1序列前面添加两个元素
list1.push_front();
list1.push_front();
cout << "list1.push_front(5) and list1.push_front(7):" << endl;
put_list(list1, "list1"); //在list1序列中间插入数据
list1.insert(++list1.begin(), , );
cout << "list1.insert(list1.begin()+1,3,9):" << endl;
put_list(list1, "list1"); //测试引用类函数
cout << "list1.front()=" << list1.front() << endl;
cout << "list1.back()=" << list1.back() << endl; //从list1序列的前后各移去一个元素
list1.pop_front();
list1.pop_back();
cout << "list1.pop_front() and list1.pop_back():" << endl;
put_list(list1, "list1"); //清除list1中的第2个元素
list1.erase(++list1.begin());
cout << "list1.erase(++list1.begin()):" << endl;
put_list(list1, "list1"); //对list2赋值并显示
list2.assign(, );
cout << "list2.assign(8,1):" << endl;
put_list(list2, "list2"); //显示序列的状态信息
cout << "list1.max_size(): " << list1.max_size() << endl;
cout << "list1.size(): " << list1.size() << endl;
cout << "list1.empty(): " << list1.empty() << endl; //对list1容器排序
list1.sort();
put_list(list1, "list1"); return ;
}

输出结果:

C++ STL中deque的用法

1、常用函数

deque的实现比较复杂,内部会维护一个map(注意!不是STL中的map容器),即一小块连续的空间,该空间中每个元素都是指针,指向另一段(较大的)区域,这个区域称为缓冲区,缓冲区用来保存deque中的数据。因此deque在随机访问和遍历数据会比vector慢。具体的deque实现可以参考《STL源码剖析》。下面给出deque的结构图:

如下是deque的使用范例:

//双向队列 deque
//by MoreWindows http://blog.csdn.net/morewindows
#include <deque>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
deque<int> ideq(); //Create a deque ideq with 20 elements of default value 0
deque<int>::iterator pos;
int i; //使用assign()赋值 assign在计算机中就是赋值的意思
for (i = ; i < ; ++i)
ideq[i] = i; //输出deque
printf("输出deque中数据:\n");
for (i = ; i < ; ++i)
printf("%d ", ideq[i]);
putchar('\n'); //在头尾加入新数据
printf("\n在头尾加入新数据...\n");
ideq.push_back();
ideq.push_front(i); //输出deque
printf("\n输出deque中数据:\n");
for (pos = ideq.begin(); pos != ideq.end(); pos++)
printf("%d ", *pos);
putchar('\n'); //查找
const int FINDNUMBER = ;
printf("\n查找%d\n", FINDNUMBER);
pos = find(ideq.begin(), ideq.end(), FINDNUMBER);
if (pos != ideq.end())
printf("find %d success\n", *pos);
else
printf("find failed\n"); //在头尾删除数据
printf("\n在头尾删除数据...\n");
ideq.pop_back();
ideq.pop_front(); //输出deque
printf("\n输出deque中数据:\n");
for (pos = ideq.begin(); pos != ideq.end(); pos++)
printf("%d ", *pos);
putchar('\n');
return ;
}

输出结果:

另外要注意一点。对于deque和vector来说,尽量少用erase(pos)和erase(beg,end)。因为这在中间删除数据后会导致后面的数据向前移动,从而使效率低下。

参考

1、STL中vector、list、deque和map的区别

2、STL系列之一 deque双向队列

【转】STL中vector、list、deque和map的区别的更多相关文章

  1. STL中vector、list、map、set区别(转载)

    list封装了链表,vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[].vector对于随机访 ...

  2. STL中vector、list、deque和map的区别

    1 vector     向量 相当于一个数组    在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capac ...

  3. C++的STL中vector内存分配方法的简单探索

    STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux  CentOS 5.2 1.代码 #include <vector> #include <stdio ...

  4. STL中vector,Map,Set的实现原理

    vector的数据安排以及操作方式,与array非常类似,两者唯一的区别是空间运用的灵活性,array是静态空间,一旦配置了就不能改变,如果你想要大一点的空间,就必须首先配置一块新空间,然后将原来的元 ...

  5. C++——STL之vector, list, deque容器对比与常用函数

    STL 三种顺序容器的特性对比: vector 可变数组,内存空间是连续的,容量不会进行缩减.支持高效随机存取,即支持[]和at()操作.尾部插入删除效率高,其他位置插删效率较低: list 双向链表 ...

  6. STL容器 vector,list,deque 性能比较

    C++的STL模板库中提供了3种容器类:vector,list,deque对于这三种容器,在觉得好用的同时,经常会让我们困惑应该选择哪一种来实现我们的逻辑.在少量数据操作的程序中随便哪一种用起来感觉差 ...

  7. STL中sort、priority_queue、map、set的自定义比较函数

    STL中,sort的默认排序为less,也就是说从小到大排序:priority_queue默认是less,也就说大顶堆:map默认是less,也就说用迭代器迭代的时候默认是小的排在前面:set默认是l ...

  8. C++ STL中vector(向量容器)使用简单介绍

    原文:http://www.seacha.com/article.php/knowledge/cbase/2013/0903/2205.html C++ vector(向量容器)是一个线性顺序结构.相 ...

  9. STL中vector的赋值,遍历,查找,删除,自定义排序——sort,push_back,find,erase

    今天学习网络编程,那个程序中利用了STL中的sort,push_back,erase,自己没有接触过,今天学习一下,写了一个简单的学习程序.编译环境是VC6.0         这个程序使用了vect ...

随机推荐

  1. C语言复习---输出魔方阵

    一:奇魔方阵 算法: 1.第一个元素放在第一行中间一列 .下一个元素存放在当前元素的上一行.下一列. .如果上一行.下一列已经有内容,则下一个元素的存放位置为当前列的下一行. 在找上一行.下一行或者下 ...

  2. spring整合curator实现分布式锁

    为什么要有分布式锁? 比如说,我们要下单,分为两个操作,下单成功(订单服务),扣减库存(商品服务).如果没有锁的话,同时两个请求进来.先检查有没有库存,一看都有,然后下订单,减库存.这时候肯定会出现错 ...

  3. ssm的架构及整合说明

    SSM,即 SpringMVC.Spring 与 MyBatis 三个框架 它们在三层架构中所处的位置是不同的,即它们在三层架构中的功能各不相同,各司其职 SpringMVC:作为 View 层的实现 ...

  4. 【转载】C# 字符串截取

    https://blog.csdn.net/maba007/article/details/78424760

  5. C#数据库发布与连接

    1. 打开相关的服务 在控制面板,打开或关闭Windows特性里面,启动相关的ASP.NET相关服务,并启用IIS Manager 2. 发布应用 3. 添加应用 在Administer tools里 ...

  6. svn 在show log 时候出现 want to go offline

    今天终于把SVN服务器给配置好了,可以正常显示log信息了. 这周以来一直都在想着怎样解决svn log 显示 no date 这一问题,一时间不知道是怎么回事,上网都没能找到很好的解决方法.今天在使 ...

  7. SSH免费登录

    SSH免费登录很简单,如果有用过git的就更简单了 只需要一下两步操作就OK: 1.生成公钥和私钥,在linx上生成公钥和私钥,执行:ssh-keygen 2.执行ssh-copy-id +ip 例如 ...

  8. 广度优先遍历(BFS )(转)

    宽度优先搜索(BFS, Breadth First Search)是一个针对图和树的遍历算法.发明于上世纪50年代末60年代初,最初用于解决迷宫最短路径和网络路由等问题. 对于下面的树而言,BFS方法 ...

  9. nnet3的代码分析

    nnet3/nnet-common.h 定义了Index,(n, t, x)三元组,表示第n个batch中第t帧. 并声明了关于Index或Cindex的一些读写操作.     nnet3/nnet- ...

  10. webpack配置模块的查找范围

    一般我们的入口文件会引入一下公共的样式文件,比如这样 import './style' 但是这个样式文件并不会生效呀,因为你的写法不对鸭,你要把文件的后缀名也要写 import './style.cs ...