List封装了链表。vector封装了数组,list和vector的最主要区别在于vector使用连续内存存储的,list是以链表形式实现的。
vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。
List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只需要改变指针的指向就可以了。
map属于标准关联容器,使用了非常高效的平衡检索二叉树,红黑树,他的插入删除效率比其他序列容器高,因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可。
set和vector的区别在于set不包含重复的数据,set和map的区别在于set只含有key,而map有一个key和key所对应的value两个元素。
1.vector
向量 相当于一个数组
在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。首先分配一个非常大的内存空间预备进行存储。
优点:
(1)不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组进行动态操作。通常体现在push_back() pop_back()
(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占用内存多
C++STL中vector容器的用法
为了可以使用vector,必须在头文件中包含下面代码:
#include <vector>
vector属于std命名域,因此需要通过命名限定
using std: :vector ; vector<int> v ;
或者连在一起使用全名:
std: :vector<int> v ;
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)的数据,无返回值
3.vector中的操作
operator[] 如: c.[i];
同at()函数的作用相同,即取容器中的数据。
#include <iostream>
#include <list>
#include <numeric>
#include <algorithm>
using namespace std;
//创建一个list容器的实例LISTINT
typedef list<int> LISTINT;
//创建一个list容器的实例LISTCHAR
typedef list<char> LISTCHAR;
void main(void)
{
LISTINT::reverse_iterator ir;
}
#include <iostream>
#include <list>
using namespace std;
typedef list<int> INTLIST;
//从前向后显示list队列的全部元素
void put_list(INTLISTlist, char *name)
{
}
//测试list容器的功能
void main(void)
{
//list1对象初始为空
//从list1序列后面添加两个元素
list1.push_back(2);
list1.push_back(4);
cout<<"list1.push_back(2) andlist1.push_back(4):"<<endl;
//从list1序列前面添加两个元素
list1.push_front(5);
list1.push_front(7);
cout<<"list1.push_front(5) andlist1.push_front(7):"<<endl;
//在list1序列中间插入数据
list1.insert(++list1.begin(),3,9);
cout<<"list1.insert(list1.begin()+1,3,9):"<<endl;
//测试引用类函数
cout<<"list1.front()="<<list1.front()<<endl;
cout<<"list1.back()="<<list1.back()<<endl;
//从list1序列的前后各移去一个元素
list1.pop_front();
list1.pop_back();
cout<<"list1.pop_front() andlist1.pop_back():"<<endl;
//清除list1中的第2个元素
list1.erase(++list1.begin());
cout<<"list1.erase(++list1.begin()):"<<endl;
//对list2赋值并显示
list2.assign(8,1);
cout<<"list2.assign(8,1):"<<endl;
//显示序列的状态信息
cout<<"list1.max_size(): "<<list1.max_size()<<endl;
cout<<"list1.size(): "<<list1.size()<<endl;
cout<<"list1.empty(): "<<list1.empty()<<endl;
//list序列容器的运算
cout<<"list1>list3: "<<(list1>list3)<<endl;
cout<<"list1<list3: "<<(list1<list3)<<endl;
//对list1容器排序
list1.sort();
//结合处理
list1.splice(++list1.begin(),list3);
}
map:
map映照容器的元素数据是一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。
map映照容器的数据结构是采用红黑树来实现的,插入键值的元素不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。
使用map容器需要头文件包含语句“#include<map>”,map文件也包含了对multimap多重映照容器的定义。
1、map创建、元素插入和遍历访问
创建map对象,键值与映照数据的类型由自己定义。在没有指定比较函数时,元素的插入位置是按键值由小到大插入到黑白树中去的,下面这个程序详细说明了如何操作map容器。

2

3

4

5

6

7

8

9

10

11



12

13

14

15

16

17

18

19

20

21

22

23



24

25

26

27

28

29

运行结果:
Bomi :96
Jack :98.5
Kate :97.5
程序编译试,会产生代号为“warning C4786” 的警告, “4786” 是标记符超长警告的代号。可以在程序的头文件包含代码的前面使用"#pragma waring(disable:4786)" 宏语句,强制编译器忽略该警告。4786号警告对程序的正确性和运行并无影响。
2、删除元素
map映照容器的 erase() 删除元素函数,可以删除某个迭代器位置上的元素、等于某个键值的元素、一个迭代器区间上的所有元素,当然,也可使用clear()方法清空map映照容器。
下面这个程序演示了删除map容器中键值为28的元素:

2

3

4

5

6

7

8

9

10

11



12

13

14

15

16

17

18

19

20

21

22

23

24



25

26

27

28

29

30

运行结果:
10 : x
25 : m
30 : a
3、元素反向遍历
可以用反向迭代器reverse_iterator反向遍历map映照容器中的数据,它需要rbegin()方法和rend()方法指出反向遍历的起始位置和终止位置。

2

3

4

5

6

7

8

9

10

11



12

13

14

15

16

17

18

19

20

21

22



23

24

25

26

27

28

运行结果:
30 : a
28 : k
25 : m
10 : x
4、元素的搜索
使用find()方法来搜索某个键值,如果搜索到了,则返回该键值所在的迭代器位置,否则,返回end()迭代器位置。由于map采用黑白树数据结构来实现,所以搜索速度是极快的。
下面这个程序搜索键值为28的元素:

2

3

4

5

6

7

8

9

10

11



12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27
