STL库
介绍
- STL是一个具有工业强度的,高效的C++程序库,包含了很多计算机科学领域里所常用的基本数据结构和基本算法;
- 六大组件:===容器(Container)、迭代器(Iterator)、算法(Algorithm)、==仿函数、适配器、分配器;
容器
定义
容器时容纳、包含一组元素或元素集合的对象;
序列式容器
- 介绍:序列式容器也称顺序容器;是将一组具有相同类型的元素以严格的线性形式组织起来,每个元素都有固定的位置;
向量(verctor)
- 功能实现: 本质上是动态数组,随机存取任何元素都能在常数事件完成;在尾端增删元素性能更高;过程:创建空间->填充数据->重建更大的空间->复制原空间数据->删除原空间->添加新数据;(性能最好)
- 只能尾插,可以下标访问
- 示例:
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char *argv[])
{vector<int> vArr;vArr.push_back(10);//尾插vArr.push_back(20);vArr.push_back(30);vArr.push_back(40);vArr.push_back(50);for (int i = 0;i < vArr.size();i++)//元素个数{cout << vArr[i] << " ";}cout << endl;vector<int>::iterator it = vArr.begin();//迭代器,存数组开始地址for (;it != vArr.end();++it)//迭代器,存数组最后一个元素后面的NULL的地址{if(*it == 30){vArr.erase(it);break;}}for (int i = 0;i < vArr.size();i++){cout << vArr[i] << " ";}cout << endl;return 0;
}
列表(list)
- 功能实现:本质是双向循环链表,在任何位置增删元素都能在常数事件完成,但随机访问偏慢;
- 可头插可尾插,可按条件删除remove_if(),可排序;
- 示例:
#include <list>
using namespace std;
int main(int argc, const char *argv[])
{list<int> lArr;lArr.push_back(10);//尾插lArr.push_back(20);lArr.push_back(30);lArr.push_front(40);//头插lArr.push_front(50);lArr.push_front(60);for (list<int>::iterator it = lArr.begin(); it != lArr.end(); it++){cout << *it << " ";}cout << endl;lArr.remove(30);//删除lArr.sort();//排序for (list<int>::iterator it = lArr.begin(); it != lArr.end(); it++){cout << *it << " ";}cout << endl;return 0;
}
双端队列(deque)
- 常用方法与list几乎相同但又缺少list的都有方法;比vector多了头插头删的功能却不如vector 性能好;支持下标访问;
关联式容器
- 介绍:元素的位置取决于特定的排序准则,和插入顺序无关;查找数据时具有非常好的性能;插入和检索的事件通常以平衡二叉树的方式实现;
集合(set)与多重集合(mulitiset)
- 功能实现:通常以红黑树实现;搜索、移除和插入拥有对数的复杂度;set容器内的元素会被自动排序,默认升序;无法使用迭代器去修改set元素,但是可以插入和删除;
- 区别:set不允许数据重复,而mulitiset允许数据重复;
- 示例:
#include <iostream>
#include <set>using namespace std;int main(int argc, const char *argv[])
{set<int> sArr;sArr.insert(50);sArr.insert(99);sArr.insert(12);sArr.insert(37);sArr.insert(46);sArr.erase(sArr.find(46));//查找元素必须存在for (set<int>::iterator it = sArr.begin(); it != sArr.end(); ++it){cout << *it << " ";}cout << endl;return 0;
}
映射(map)与多重映射(mulitimap)
- 特点:map提供的是一种键值对容器,里面的数据都是成对出现的,每一对中的第一个称之为关键字(key)每个关键字只能在map中出现一次;第二个称之为该关键字的对应值;
- 区别:mulitimap与map唯一的区别是mulitimap的键值key可以重复,导致map支持[]运算符,而mulitimap不支持;
- 用法:
#include <iostream>
#include <map>using namespace std;int main(int argc, const char *argv[])
{map<int,string> mStu;mStu[1] = "张三";mStu[2] = "李四";mStu[3] = "王五";for (map<int,string>::iterator it = mStu.begin(); it != mStu.end(); ++it){cout << it->first << "=>" << it->second << endl;}map<int,string>::iterator it = mStu.find(2);if(it != mStu.end()){cout << it->second << endl;mStu.erase(it);}for (map<int,string>::iterator it = mStu.begin(); it != mStu.end(); ++it){cout << it->first << "=>" << it->second << endl;}return 0;
}
迭代器
- 概念:迭代器是一种检查容器内元素并遍历元素的数据类型(本质上通过类实现);C++更趋向于使用迭代器而不是下标操作;标准库为每一种标准容器定义了一种迭代器类型,而极少数容器支持下标操作访问容器元素;
- 定义与初始化:每种容器都定义了自己的迭代器类型;每种容器定义了一对名为begin和end的函数用于迭代器返回;
- 四种迭代器:正向迭代器(iterator)、常量正向迭代器(const_iterator)、反向迭代器(reversr_iterator)、常量反向迭代器(const_reversr_iterator)。
- 迭代器类型:迭代器主要支持两类,随机访问和双向访问。其中vector和deque支持随机访问,list、set、map等支持双向访问。
1)随机访问:提供了对数组元素进行快速随机访问以及在序列尾部进行快速插入和删除操作;
2)双向访问:插入和删除所花费的时间是固定的,与位置无关。 - 常见运算符操作:
- 使迭代器失效的操作:
1)由于一些对容器的操作如删除元素或移动元素会修改容器的内在状态,会使原本指向被移动元素的迭代器失效,也可能使其他迭代器失效(若迭代器指向的元素被删除,迭代器变成野指针,迭代器失效)。
2)使用无效的迭代器是没有意义的,可能会导致和使用空指针相同的问题,所以使用迭代器时,需要特别留意哪些操作会使迭代器失效,使用无效迭代器会导致严重的运行错误。
算法
- 头文件:
1) 它是由一大堆模板函数组成的,交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
2) 只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作;
3) 定义了一些模板类,用以声明函数对象; - 四大类:
1)非可变序列算法:指不直接修改其所操作的容器内容的算法;
2)可变序列算法:指可以修改他们所操作的容器内容的算法;
3)排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作;
4)数值算法:对容器内容进行数值计算。