1. vector向量:相当于一个数组
连续存储结构,每个元素在内存上是连续的;支持高效的随机访问和在尾端插入/删除操作,但其他位置的插入/删除操作效率低下;相当于一个数组,但是与数组的区别为:内存空间的扩展。vector支持不指定vector大小的存储,但是数组的扩展需要程序员自己写。
优点:
- 不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组进行动态操作。通常体现在push_back() pop_back()
- 随机访问方便,即支持[ ]操作符和vector.at()
- 节省空间
缺点:
- 在内部进行插入删除操作效率低
- 只能在vector的最后进行push和pop,不能在vector的头进行push和pop
- 当动态添加的数据超过vector默认分配的大小时要进行整体的重新分配、拷贝与释放
vector的使用:
在头文件中包含#include <vector>;vector属于std命名域的,因此需要通过命名限定using std::vector或using namespace std;
1.1 vector的声明
函数
|
描述
|
vector<Type> c; | 创建一个空的vector; |
vector<Type> c1(c2); | 创建一个vector c1,并用c2去初始化c1; |
vector<Type> c(n) ; | 创建一个含有n个Type类型数据的vector; |
vector<Type> c(n,elem); | 创建一个含有n个Type类型数据的vector,并全部初始化为elem; |
vector<Type> vector(begin,end); | 创建一个从begin到end的vector; |
c.~vector<ElemType>(); | 销毁所有数据,释放资源; |
1.2 vector容器中的函数
函数
|
描述
|
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.resize(size_type size, TYPE val); | 重新设置vector的容量 |
c.reserve(size_type size); | 预留至少共容纳size个元素的空间. |
c.erase(p);
c.erase(begin,end);
|
删除指针p指向位置的数据,返回指向下一个数据位置的指针(迭代器)
删除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);
c.insert(p,n,elem);
c.insert(p,begin,end);
|
在指针p指向的位置插入数据elem,返回指向elem位置的指针
在位置p插入n个elem数据,无返回值
在位置p插入在区间[begin,end)的数据,无返回值
|
2.list双向链表
非连续存储结构,具有双链表结构,每个元素有一对前向和后向指针,支持前向/后向遍历。高效的随机插入/删除操作,但随机访问效率低下,且由于需要额外维护指针,开销也比较大。每一个结点都包括一个信息块Info、一个前驱指针Pre、一个后驱指针Post。可以不分配必须的内存大小方便的进行添加和删除操作。
优点:
- 不使用连续内存完成动态操作
- 在内部方便的进行插入和删除操作
- 可在两端进行push、pop
缺点:
- 不能进行内部的随机访问,即不支持[ ]操作符和at()
- 相对于verctor占用内存多
list的使用:
在头文件中包含#include <list>;vector属于std命名域的,因此需要通过命名限定using std::list或using namespace std;
2.1 list的声明
函数
|
描述
|
list<Type> list ; | 创建一个空的list; |
list<Type> list1(list2); | 创建一个list list1,并用list2去初始化list1; |
list<Type> list(n) ; | 创建一个含有n个Type类型数据的list; |
list<Type> list(n,elem); | 创建一个含有n个Type类型数据的list,并全部初始化为elem; |
list <Type> list(begin,end); | 创建一个从begin到end的list; |
c.~list<ElemType>(); | 销毁所有数据,释放资源; |
2.2 list容器中的函数
函数
|
描述
|
list.push_front (num); | 从前面向list中添加数据 |
list.push_back (num); | 从后面向list中添加数据 |
list.pop_front (); | 删除第一个元素 |
list.pop_back (); | 删除最后一个元素 |
list.begin(); | 返回指向容器最开始位置数据的指针 |
list.end(); | 返回指向容器最后一个数据单元的指针+1 |
list.front(); | 返回容器最开始单元数据的引用 |
list.back(); | 返回容器最后一个数据的引用 |
list.max_size(); | 返回容器的最大容量 |
list.size(); | 返回当前容器中实际存放元素的个数 |
list.capacity(); | 同c.size() |
list.resize(size_type size, TYPE val); | 重新设置deque的容量 |
list.reserve(size_type size); | 预留至少共容纳size个元素的空间. |
list.erase(p);
list.erase(begin,end);
|
删除指针p指向位置的数据,返回指向下一个数据位置的指针(迭代器)
删除begin,end区间的数据,返回指向下一个数据位置的指针(迭代器)
|
list.remove(); | 删除一个元素,参数是元素的值或者是对象 |
list.clear(); | 清除所有数据 |
list.rbegin(); | 将list反转后的开始指针返回(就是原来的end-1) |
list.rend(); | 将list反转后的结束指针返回(就是原来的begin-1) |
list.empty(); | 判断容器是否为空,若为空返回true,否则返回false |
list1.swap(list2); | 交换两个容器中的数据 |
list.insert(p,elem);
list.insert(p,n,elem);
list.insert(p,begin,end);
|
在指针p指向的位置插入数据elem,返回指向elem位置的指针
在位置p插入n个elem数据,无返回值
在位置p插入在区间[begin,end)的数据,无返回值
|
list1.merge(list2); | 合并两个list(list1和list2已经排好顺序,合并之后list1仍然是有序的) |
index=find(list1.begin(),list1.end(),'f');
list1.splice(index,list2);
list1.splice(index1, list2, index2);
list1.splice(index1,list2,index2,index3);
|
先的找到要插入的位置,在该位置的前一个插入;
将第二个链表插入到第一个链表中
将list2中的元素index2,合并到list1的index1之前
把链表list2中的一段插入到另一个链表list1中
|
list.unique(); | 删除list中重复的元素 |
list.sort(); | 将list里的元素排序 |
list.reverse(); | 将list里的数据倒序排列 |
list.assign(n.elem)
list.assign(bedin,end)
|
将n个elem的拷贝赋值给list
将[begin,end)区间的数据赋值给list
|
3.deque双端队列
连续存储结构, deque是在功能上合并了vector和list。即其每个元素在内存上也是连续的,类似于vector。不同之处在于,deque提供了两级数组结构, 第一级完全类似于vector,代表实际容器;另一级为容器的首位地址。这样,deque除了具有vector的所有功能外,还支持高效的首/尾端插入/删除操作。
优点:
- 随机访问方便,即支持[ ]操作符和vector.at()
- 在内部方便的进行插入和删除操作
- 可在两端进行push、pop
缺点:
- 占用内存多
- 支持随机访问,即支持[]以及at(),但是性能没有vector好
- 可以在内部进行插入和删除操作,但性能不及list
使用区别:
- 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
- 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
- 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque
deque的使用:
在头文件中包含#include <deque>;deque属于std命名域的,因此需要通过命名限定using std::deque或using namespace std;
3.1 deque的声明
函数
|
描述
|
deque <Type> deque; | 创建一个空的deque; |
deque<Type> deque1(deque2); | 创建一个deque deque1,并用deque2去初始化deque1; |
deque <Type> deque(n) ; | 创建一个含有n个Type类型数据的deque; |
deque<Type> deque(n,elem); | 创建一个含有n个Type类型数据的deque ,并全部初始化为elem; |
deque<Type> deque(begin,end); | 创建一个从begin到end的deque; |
c.~deque<ElemType>(); | 销毁所有数据,释放资源; |
3.2 deque容器中的函数
函数
|
描述
|
deque.at(index); | 返回指定index位置处的元素 |
deque.push_front (num); | 从前面向deque中添加数据 |
deque.push_back (num); | 从后面向deque中添加数据 |
deque.pop_front (); | 删除第一个元素 |
deque.pop_back (); | 删除最后一个元素 |
deque.begin(); | 返回指向容器最开始位置数据的指针 |
deque.end(); | 返回指向容器最后一个数据单元的指针+1 |
deque.front(); | 返回容器最开始单元数据的引用 |
deque.back(); | 返回容器最后一个数据的引用 |
deque.max_size(); | 返回容器的最大容量 |
deque.size(); | 返回当前容器中实际存放元素的个数 |
deque.resize(size_type size, TYPE val); | 重新设置deque的容量 |
deque.erase(p);
deque.erase(begin,end);
|
删除指针p指向位置的数据,返回指向下一个数据位置的指针(迭代器)
删除begin,end区间的数据,返回指向下一个数据位置的指针(迭代器)
|
deque.clear(); | 清除所有数据 |
deque.rbegin(); | 将deque反转后的开始指针返回(就是原来的end-1) |
deque.rend(); | 将deque反转后的结束指针返回(就是原来的begin-1) |
deque.empty(); | 判断容器是否为空,若为空返回true,否则返回false |
deque1.swap(deque2); | 交换两个容器中的数据 |
deque.insert(p,elem);
deque.insert(p,n,elem);
deque.insert(p,begin,end);
|
在指针p指向的位置插入数据elem,返回指向elem位置的指针
在位置p插入n个elem数据,无返回值
在位置p插入在区间[begin,end)的数据,无返回值
|
deque.assign(n.elem)
deque.assign(bedin,end)
|
将n个elem的拷贝赋值给deque
将[begin,end)区间的数据赋值给deque
|
4.set集合
set容器用来存储唯一元素,并且这些元素按照一定的规则排序,其内部数据结构为红黑树。在一个集合里面,每个元素同时也是自身的关键字,与map相比,set的key与value是同一个值,所以每个元素必须是唯一的。同时,一旦某个元素插入到容器内,则不能修改其中任何元素,类比map,在map中也不能修改key。但set容器可以插入与删除。
set的使用:
在头文件中包含#include <set>;deque属于std命名域的,因此需要通过命名限定using std::deque或using namespace std;
4.1 set的声明
函数
|
描述
|
set <Type> deque; | 创建一个空的set; |
set<Type> set1(set2); | 创建一个set1,并用set2去初始化set1; |
set <Type> set(n) ; | 创建一个含有n个Type类型数据的set; |
set<Type> set(n,elem); | 创建一个含有n个Type类型数据的set,并全部初始化为elem; |
set<Type> set(begin,end); | 创建一个从begin到end的set; |
c.~set<ElemType>(); | 销毁所有数据,释放资源; |
4.2 set容器中的函数
函数
|
描述
|
set.begin(); | 返回指向容器最开始位置数据的指针 |
set.end(); | 返回指向容器最后一个数据单元的指针+1 |
set.find() | 查找一个元素,如果容器中不存在该元素,返回值等于s.end() |
set.lower_bound() | 返回第一个大于或等于给定关键值的元素 |
set.upper_bound() | 返回第一个大于给定关键值的元素 |
set.equal_range() | 返回一对定位器,分别表示 第一个大于或等于给定关键值的元素 和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于s.end() |
set.size(); | 返回当前容器中实际存放元素的个数 |
set.erase(p);
set.erase(begin,end);
|
删除指针p指向位置的数据,返回指向下一个数据位置的指针(迭代器)
删除begin,end区间的数据,返回指向下一个数据位置的指针(迭代器)
|
set.clear(); | 清除所有数据 |
set.empty(); | 判断容器是否为空,若为空返回true,否则返回false |
set.insert(p,elem);
set.insert(p,n,elem);
set.insert(p,begin,end);
|
在指针p指向的位置插入数据elem,返回指向elem位置的指针
在位置p插入n个elem数据,无返回值
在位置p插入在区间[begin,end)的数据,无返回值
|
结构体是你自己设计的,在类中重载operator<
bool operator <(const Object& o) const;
结构体是别人设计的,类中没有重载operator<
set<int, cmp> s;
struct cmp{
bool operator () (const int &a, const int &b)
{
return a > b;
}
};
| 自定义排序方式 |
4.map
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。map内部自建一颗红黑树,这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。
map的使用:
在头文件中包含#include <map>;deque属于std命名域的,因此需要通过命名限定using std::deque或using namespace std;
4.2 map容器中的函数
函数
|
描述
|
map.find() | 查找一个元素,如果容器中不存在该元素,返回值等于map.end() |
map.count() | 统计map中某个键值出现的次数,因为map中键值唯一,所以此方法可以用来检测某键值是否存在 |
map.lower_bound() | 返回要查找关键字的下界(是一个迭代器) |
map.upper_bound() | 返回要查找关键字的上界(是一个迭代器) |
map.equal_range() | pair里面第一个变量是lower_bound返回的迭代器,pair里面第二个迭代器是upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字 |
map.size(); | 返回当前容器中实际存放元素的个数 |
map.erase(val);
map.erase(p);
map.erase(begin,end);
|
删除关键字删除
删除指针p指向位置的数据,返回指向下一个数据位置的指针(迭代器)
删除begin,end区间的数据,返回指向下一个数据位置的指针(迭代器)
|
map.clear(); | 清除所有数据 |
map.empty(); | 判断容器是否为空,若为空返回true,否则返回false |
map1.swap(map2); | 交换两个容器中的数据 |
map.insert(pair<int,string>(1, “one”));
map.insert(map<int,string>::value_type (1, “one”));
map[1] = “one”;
|
当map中有这个关键字时,insert操作是插入数据不了的
数组方式就不同,它可以覆盖以前该关键字对应的值
|
结构体是你自己设计的,在类中重载operator<
bool operator <(const Object& o) const;
结构体是别人设计的,类中没有重载operator<
map<int, cmp> s;
struct cmp{
bool operator () (const int &a, const int &b)
{
return a > b;
}
};
| 自定义排序方式 |