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;