在c++中,容器指的是可以容纳各类数据类型的通用数据数据结构,是类模板。 好比set类模板:c++
template <class _Key, class _Compare = less<_Key>,算法
class _Allocator = allocator<_Key> >编程
class _LIBCPP_TYPE_VIS_ONLY set数组
C++的容器主要分为三种:顺序容器、关联容器和容器适配器。数据结构
而访问容器元素咱们须要迭代器(引入容器头文件就能够了,不须要单独由于头文件),迭代器有如下几个属性:less
1.用于指向顺序容器和关联容器的元素编程语言
2.用法和指针相似函数
3.有const(容器类名::iterator 变量名)和非const两种(容器类名::const_iterator 变量名)性能
4.经过迭代器能够读取它指向的元素学习
5.非const迭代器和能够修改其指向的元素
何为顺序容器,也就是说元素的位置是顺序插入的,插入位置与元素的值无关,核心是容器没有排序。 顺序容器都具备如下10个成员函数:
#返回迭代器
begin
end
rbegin //返回指向最后一个元素的迭代器
rend
#返回元素引用
front
back
#其余
erase(删除区间时返回被删除元素后面的迭代器;也可删除一个或几个元素)
clear
push_back
pop_back
顺序容器有如下三种:
1.vector动态数组 头文件<vetor>
元素在内存中是连续存放的。
随机存取时间:常数时间(由于能够经过下标直接访问到地址)。
在尾部增删元素一般是常数时间(正常是常数时间,若是超出了默认分配的元素个数,会从新分配存储空间,此时会消耗更多时间)。
在中间或者头部增删元素:o(n)(会移动其余元素的位置)。
迭代器类型:随机访问(支持下标访问、随机移动,例:a[i])。
查询时间:o(n)(由于没有排序,只能现行查找,效率较低)。
可见vector在中间或者头部增删元素性能较低。
优势:内存和C彻底兼容、高效随机访问、节省空间
缺点:内部插入删除元素代价巨大、动态大小查过自身容量须要申请大量内存作大量拷贝。
构造函数:
vector();
vector(int n);
vector(int n, const T &a); //把n个元素初始化为a
vector(iterator first,iterator last); //初始化为其余容器上区间[first,last)一致的内容
经常使用成员函数
void pop_back();
void push_back(const T &val);
int size();
T & font();
T & back();
deque[读:dek,以前常常读dkju:]双向队列 头文件<deque>
元素在内存中连续存放(连续内存的容器有个明显的缺点,就是有新元素插入或老元素删除的时候,为了给新元素腾出位置或者填充老元素的空缺,同一块内存中的其余数据须要进行总体的移位,这种移位的拷贝代价有时是很是巨大的。deque其实是分配到不一样内存块,经过链表把内存块连在一块儿,再进行连续存放,是list与vector的折中)。
随机存取时间:常数时间(仅次于vector,由于有可能存在尾部的内存位置在头部以前的场景)。
在两端增删元素一般是常数时间。(deque不像vector没有容量,不须要从新分配内存空间。这是由于deque由动态分配的连续空间,即缓冲区,组合而成,随时能够增长一段新的空间连接起来。它没有必要像vector那样“因旧空间不足而从新分配2倍的空间,而后复制元素,再释放旧空间”。当从新分配缓冲区时,耗时增长)。
在中间插入:时间复杂度较高。
迭代器类型:随机访问(效率低于vector)。
查询时间:o(n)(缘由同上)。
优势:高效随机访问、内部插入删除元素效率方便、两端push、pop效率很高 。
缺点:内存占用比较高 。
list双向链表 头文件<list>
元素在内存中不连续分配(由于指针能够获取先后元素的地址),因此不支持随机存取。
在任何位置增删元素时间:常数时间。
查询时间:o(n)(缘由同上)。
迭代器类型:双向(不支持下标访问,不支持迭代器的比较运算符,和+-运算符)
优势:任意位置插入删除元素常量时间复杂度、两个容器融合是常量时间复杂度
缺点:不支持随机访问、比vector占用更多的存储空间
经常使用成员函数:(注意这些在顺序容器中都是list独有的)
push_front
pop_front
sort //不支持STLsort算法
remove
unique
merge
reverse
splice
特别说明,list的sort函数有无参和compare两个版本
list<T> classname
classname.sort(compare); //compare自定义
classname.sort();
关联的意思就是元素是排序的。
插入与检索元素时间: o(log(N))(由于经过红黑二叉树实现,时间与平衡二叉树一致)。
须要注意的是,STL中有些算法好比sort,binary_search须要经过随机访问迭代器访问容器中的元素,所以list以及关联容器就不能支持该算法!
主要包括如下4种:
set
multiset
map
multimap
除了个容器都有的成员函数外,它们都有如下成员函数
find
lower_bound
upper_bound
equal_range
count
insert
map与set的不一样点在于,map中存放的元素有且仅有两个成员变量,first(相似于key),second(相似于value),map能够根据first对元素排序和检索。
set与multiset的不一样在于,后者容许存在相同值的元素。 map与multimap的不一样在于,后者容许存在相同的first值的元素。
这个概念听起来有点抽象,其实就是STL帮咱们抽象了实际工做中所须要的数据操做方式。举个栗子,交流电能够有任意的传输电压,可是实际生活中咱们只须要220v就够了,变压器帮咱们实现了这个基本的功能。同理,容器的操做方式多种多样,可是其实咱们只须要他们按照实际的一些规范来操做便可。
他们都有如下3个成员函数:
push
top
pop
STL中的排序,查找,变序算法都不适合容器适配器(由于容器适配器的元素位置不可随意改变,而且访问有必定的访问规则,不支持随机访问)。
stack 栈 头文件<stack>
是一个有限序列,并知足序列中被删除、检索和修改的项只能是最近插入序列的项(栈顶项)。也即,先进先出LIFO。
能够用vector,deque,list(性能最差)实现,编译器缺省是用deque实现的。
好比,在程序调试中,错误堆栈就是一种应用。
queue 队列 头文件 <queue>
插入只能够在尾部进行,删除、检索和修改只容许从头部进行。先进先出FIFO。
queue因为pop,push发生在对头,因此不能用vector实现,能够用list,deque实现,编译器缺省用deque实现。
好比,应用于须要保证消息顺序性的场景,如消息队列。
priority_queue 优先级队列 头文件<queue>
最高优先级元素老是第一个出列。
它需采用堆排序来保证元素老是在最前面,所以要求随机访问,因此不能使用list实现,能够用vector和deque实现,编译器缺省状况下用vector实现。
好比,操做系统的线程的调度算法,有的是按照优先级来调度的。
1.若是须要随机访问,用vector;
2.若是存储元素的数目已知,用vector;
3.须要任意位置随机插入删除,用list;
4.常常在容器的首部尾部插入删除元素,用deque;
5.元素结构复杂用list,也能够用vector存储指针(须要额外的精力去维护内存),看需求;
6.若是操做是基于键值,用set/map;
7.若是须要常常的搜索,用map/set。
C语言就是一个既能够强化思惟能力,又能够打好编程基础的编程语言,对这个感兴趣的同窗来小编这里学学吧。即便是零基础的学习者,均可以一块儿成长进步。