身为C++标准库最重要的组成部分,STL不仅是一个可复用组件库,而且是一个保罗算法与数据结构的软件框架,对软件开发而言,STL是尖甲利刃,可以节省你许多时间;对编程技术而言,STL是藏宝库,所有与编程工作最有直接密切关联的一些最被广泛运用的数据结构和算法,STL都有实现,并符合最佳效率,极大的提高了工作效率和代码质量,同时代码复用的目的。
先来说一下STL的六大组件:
1.容器
2.算法
3.迭代器
4.仿函数
5.适配器
6.空间配置器
一、容器
容器分为:
顺序容器:vector:向量容器(底层是内存可自动增长的数组(2倍))
deque:双端队列容器(底层是动态开辟的二维数组)
list:双向链表容器(底层是双向链表)
关联容器:底层是红黑树(集合和映射表,时间复杂度为o(log2n))
set:单重集合 key
multiset:多重集合 key
map:单重映射表 key<->value
multimap:多重映射表 key<->value key可以重复
容器适配器
stack:允许在底层数据结构的一端插入和删除操作(先进后出),堆栈能够用任何序列容器实现:vector、list、deque,默认是deque实现。
queue:允许在底层数据结构的首尾插入元素,队列能够用list和deque实现,默认是用deque。
priority_queue:能够按照有序的方式在底层数据结构中执行插入操作,也能从底层数据结构的前面执行删除操作,可以用vector和deque实现,默认是vector。
二、算法
STL的算法主要由头文件<algorithm>、<numeric>和<functional>组成。<algorithm>它是由一大堆模板函数组成,耦合性低,其中常用到的功能有比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。<numeric>包含一些序列上的简单运算的模板函数,加法和乘法。<functional>则定义了一些模板类,用以声明函数对象。
三、迭代器
迭代器具体实现在<iterator>头文件中,大多数时候可以把它理解为指针,它可以说是容器物件上遍访的接口,把抽象容器和通用算法有机结合起来。
四、仿函数
仿函数(函数对象),顾名思义就是使一个类的使用看上去像一个函数,就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类,仿函数就是重载的类,并且重载函数要为const。
五、适配器
适配器是用来修改其他组件接口的STL组件,是带有一个参数的类模板(操作值的数据类型)。STL定义了3中类型的适配器:容器适配器、迭代器适配器、函数适配器。
六、空间配置器
空间配置器提供容器分配和管理内存功能,统一的内存管理使得STL库的可用性、可移植性、效率都有了很大的提高。SGI- STL的空间配置器有2种,一种仅仅对c语言的malloc和free进行了简单的封装,而另一个设计到小块内存的管理等,运用了内存池技术等。在SGI-STL中默认的空间配置器是第二级的配置器。
SGI使用std::alloc作为默认的配置器。
alloc把内存配置和对象构造的操作分开,分别由alloc::allocate()和::construct()负责,同样内存释放和对象析够操作也被分开分别由alloc::deallocate()和::destroy()负责。这样可以保证高效,因为对于内存分配释放和构造析够可以根据具体类型(type traits)进行优化。比如一些类型可以直接使用高效的memset来初始化或者忽略一些析构函数。对于内存分配alloc也提供了2级分配器来应对不同情况的内存分配。
第一级配置器直接使用malloc()和free()来分配和释放内存。第二级视情况采用不同的策略:当需求内存超过128bytes的时候,视为足够大,便调用第一级配置器;当需求内存小于等于128bytes的时候便采用比较复杂的memeory pool的方式管理内存。
附:vector的基本操作:
(1)创建vector对象,vector<int> vec;数组
(2)创建vector对象,vector<vector<int>> vec;数组
(3)尾部插入数字:vec.push_back(a)
(4)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的。
(5)使用迭代器访问元素.vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;
(6)插入元素: vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;
(7)删除元素: vec.erase(vec.begin()+2);删除第3个元素vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
8)向量大小:vec.size();
(9)清空:vec.clear();