数据结构学习小记-STL
STL
- 
STL是标准模板库,有以下13个头文件,algorithm, deque,functional,iterator,vector,list, map, memory, numeric, queue, set, stack, utility. 
- 
STL包括以下几大内容, 容器(container), 迭代器(iterator), 算法(algorithm), 仿函数(function object); 
- 
容器:一种数据结构,如list,vector,stack,queue. 
- 
迭代器:一种特殊的指针,提供了访问容器中对象的方法,利用迭代器可以快速而安全的堆容器内容进行操作或是进行算法模板的使用 
- 
算法:一类常用的算法模板,可以对容器进行操作,同时也能让算法类本身可以针对数组或者是自定义结构体等结构进行直接的操作。 
- 
仿函数:一种行为类似函数,可以理解为一种高即的重载了()操作符的结构体与类。 
- 
迭代适配器(iterator adaptor): 一种用来修饰容器或者仿函数的接口,使得迭代适配器使算法能够以逆向模式、安插模式进行工作,甚至还可以与流配合,对容器起到非常大的辅助作用,同时还将迭代器进行了更高级别的抽象。 
- 
空间配置器(allocator): 负责空间的配置与管理,重点就是对容器的空间申请和空间释放进行管理,可以理解为malloc和free的函数,c++的new 和delete关键字。 
Vector容器
- 
vector是一个动态创建空间,且预先加载了常用的数组操作的数组。 
- 
push_back(),pop_back(),insert(),erase(),clear(),size(),capacity() 
List容器
- 常用接口push_front(),pop_front(),push_back(),pop_back(),insert(),erase(),sort(),reverse()
Stack容器
- 常用接口top(),push(),pop(),empty(),
队列容器
- 常用接口push(),pop(),front(),back(),size(),empty()
优先队列
- 
优先队列是一种极其特殊的队列,与标准的队列使用线性结构进行计算不同,优先队列的底层是以散列的状态(非线性)表现的,他与标准的队列有如下的区别,标准的队列遵从严格的先进先出,优先队列并不遵从标准的先进先出,而是对每一个数据赋予一个权值,根据当前队列权值的状态进行排序,使得权值最大(或最小)的永远排在队列的最前面。 
- 
priority_queue<T, Container, Compare>,常用接口,push(),pop(),top(),empty(), 
Set容器
- 
Set属于关联式容器,也是STL中最实用的容器,关联式容器依据特定的排序准则,自动为其元素排序。Set集合的底层使用一颗红黑树,其属于一种非线性的数据结构,每一次插入数据都会自动进行排序,注意,不是需要排序时再排序,而是每一次插入数据的时候其都会自动进行排序。因此,Set中的元素总是顺序的。 
- 
Set的性质有:数据自动进行排序且数据唯一,是一种集合元素,允许进行数学上的集合相关的操作。 
- 
我们使用了auto进行了迭代器类型的自动识别,省去了我们的声明迭代器的那一部分内容,这使得代码更加简化。C98标准和C11标准使用方法不一样。 
for (auto it=s.cbegin(); it!=s.cend(); ++it)
  cout << *it << ' ';
- 常用接口insert(), erase(), clear(),find()
集合论
- 在数学上的并运算我们可以使用set_union()函数进行实现,而交运算我们也可以使用set_intersection()函数进行实现,差集则使用set_difference()函数实现。
Map容器
- 
map也是一种关联容器,它是 键—值对的集合,即它的存储都是以一对键和值进行存储的,Map通常也可以理解为关联数组(associative array),就是每一个值都有一个键与之一一对应,因此,map也是不允许重复元素出现的。map也具备set的相关功能,底层也会将元素进行自动排序。 
- 
常用接口insert(),erase(),clear(),find(),size() 
Pair类模板
- 
pair将两个数据合成一组数据,对于map而言,key和value需要分开来进行使用和声明,使用pair可以合二为一(但是数据输出时依旧要分离),第二则是当我们的函数需要返回两个数据的时候,可以使用pair。Pair的实现是一个结构体而不是一个类因此可以直接使用pair的成员变量。pair将一对值(可以有不同的数据类型)和为一个值。 
- 
pair的标准头文件,#include <utility>, pair中的两个元素可以用first和second来进行访问;可以使用make_pair来生成我们所需要的pair,使用make_pair不仅仅让我们免去了对两个变量进行分开来的访问赋值,同时make_pair也智能的接受变量的类型,不需要再度指定,也就是说,make_pair本身是接受隐式类型转换的,比如定义的是一个int类型,使用make_pair传入一个float类型的参数,make_pair不会报错,而是会自动的进行一个类型转换,将float变为int。 
Multiset和Multimap容器
- 
Multiset是set集合容器的一种,其拥有set的全部内容,在此基础之上,multiset还具备了可以重复保存元素的功能,因此会有略微和set的差别。Multise容器在执行insert()时,只要数据不是非法数据和空数据,insert就总是能够执行,无论时一个数据还是一段数据。Multiset容器中的find()函数回返回和参数匹配的第一个元素的迭代器,即使存在多个元素也只是返回第一个,如{10,20,20,20}搜索20进行匹配将会返回第二个参数,如果没有符合的参数则结束迭代器。 
- 
Multimap时map映射容器的一种,其拥有map的全部内容,并在此基础之上,multimap还具有了可以重复保存元素的功能,与上文的mutliset差不多,任何进行访问单个值得语句访问均只会返回第一个位置,这里不再多说,而是举一个实际中可能用得到得例子。有没有一种方法,使得一个key值能够对应多个value,产生一种诸如一个学生有多门考试成绩一样的映射我们都知道map关联容器是使得一个数据与另一个数据发生映射的容器,通过key得到value产生一一对应,那么multimap在此基础上使得map元素可以重复,因此这种情况可以使用multimap。 
如何设计函数多返回值
- 全局变量
- 双返回值,pair,
- 指针返回法
- 结构体返回法,设计结构体
如何加速输入输出效率
- 
遇到大数据时,往往读写文件成了程序运行速度的瓶颈,需要更快的读取方式。相信几乎所有的C++学习者都在cin机器缓慢的速度上栽过跟头,有很多案例中提供几个数据,却在后台测评却提供了近千,近万的数据量是常事,而很多人会发现,明明算法正确的问题,却总是在超时,但把自己的输入换成scanf,输出换成printf之后莫名其妙又可以通过了,于是便冷眼相对C++的cin与cout。 
- 
在C++中,cin与cout往往不需要我们手动设置格式而变得灵活,因此更趋向于我们便捷式的使用,但这并不是说cin与cout就一定比scanf和printf慢,我们可以通过C++输入输出流解除绑定的方式进行加速,使其提升至C语言scanf和printf般的速度。 
- 
cin在为了与scanf保持同步,设置了一个缓冲区,为了保证各位混用两者的情况不会出错,利用这个缓冲区进行同步,不至于发生指针错误造成乱码,因此cin会牺牲一点点效率,而这一点点的效率,在大数据读取和运算的时候也会产生极大的影响,我们可以通过sync_with_stdio(false)的方式取消这个缓冲区,让cin变成和scanf一样的效率。 a) sync_with_stdio 这个函数是一个“是否兼容stdio”的开关,C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起,默认情况为sync_with_stdio(ftrue),即开启。 b) cin.tie(0),cout.tie(0); cin.tie(NULL);cout.tie(NULL);只解除的是C++运行库层面的对数据传输的绑定,stdin和stdout应该在更底层的操作系统层面有绑定,没有解除,也就是说,cin.tie(0)与cout.tie(0)的方式是继续松绑c++传输的效率。 

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号