STL是一个具有工业强度的、高效的C++程序库,包含了很多计算机领域里所常用的基本数据结构和基本算法,它拥有六大组件1.容器(是一种数据结构,如list,vector和deques,以类模板的方法提供)2.迭代器(提供了访问容器中对象的方法)3.算法(用来操作容器中的数据的模板函数)4.仿函数 5.适配器 6.分配器
容器
容器是容纳、包含一组元素或元素集合的对象
序列式容器
将一组具有相同类型的元素以严格的线性形式组织起来,每个元素都有固定位置,也称为顺序容器
1.向量(vector)
本质上是动态数组,随机存取任何元素都能在常数事件完成,在尾端增删元素性能高
建立空间->填充数据->重建更大空间->复制原空间数据->删除原空间->添加新数据
常用方法:
示例:
#include<iostream>
#include<vector>
using namespace std;
int main(int argc, const char *argv[])
{
vector <string> varr;
varr.push_back("A");
varr.push_back("B");
varr.push_back("C");
varr.push_back("D");
varr.push_back("F");
varr.at(3) = "E";
for(int i = 0; i < varr.size(); ++i)
{
cout << varr[i] << " ";
}
cout << endl;
cout << "-----------------" << endl;
vector<string>::iterator it = varr.begin();
for(; it!= varr.end(); ++it)
{
if(*it == "E")
{
varr.erase(it);
break;
}
}
for(int i = 0; i < varr.size(); ++i)
{
cout << varr[i] << " ";
}
cout << endl;
return 0;
}
2.列表(list)
本质是双向循环链表,在任何位置增删元素都能在常数时间完成,但随机访问偏慢
常用方法:
示例:
#include<iostream>
#include<list>
using namespace std;
bool single_digit(const int &value)
{
return (value<10);
}
int main(int argc, const char *argv[])
{
list <int> lArr;
lArr.push_back(1);
lArr.push_back(2);
lArr.push_back(3);
lArr.push_front(40);
lArr.push_front(50);
lArr.push_front(60);
lArr.remove(3);
lArr.remove_if(single_digit);
lArr.sort();
for(list<int>::iterator it = lArr.begin(); it != lArr.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
3.双端队列(deque)
本质是动态数组,随机存取任何元素都能在常数事件完成,性能仅次于vector,在两端增删元素具有较好性能
常用方法:
与list几乎一致,缺少list独有的方法
关联式容器
元素位置取决于特定的排序准则,和插入顺序无关,查找数据时具有非常好的性能,插入和检索的事件通常以平衡二叉树的方式实现
1.集合(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(12);
sArr.insert(34);
sArr.insert(56);
sArr.insert(78);
sArr.insert(89);
set<int>::iterator it2 = sArr.find(34);
{
sArr.erase(it2);//查找的元素必须存在
}
for(set<int>::iterator it = sArr.begin(); it != sArr.end(); ++ it)
{
cout << *it << " ";
}
cout << endl;
set<int>:: iterator it = sArr.lower_bound(60);
cout << *it << endl;
return 0;
}
2.映射(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 = {{10,"A"},{20,"B"}};
mStu.insert(pair<int,string>(30,"C"));
mStu.insert(map<int,string>::value_type(40,"D"));
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(10);
{
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)
反向迭代器(reverse_iterator)
常量反向迭代器(const_reverse_iterator)
不同容器所支持的迭代器类型:
迭代器类型主要支持两类,随机访问和双向访问。其中vector和deque支持随机访问,list,set,map等支持双向访问
1.随机访问:提供了对数组元素进行快速随机访问以及在序列尾部进行快速插入和删除操作。
2.双向访问:插入和删除所花费的时间是固定的,与位置无关。
常见的操作运算符:
由于一些对容器的操作如删除元素或移动元素会修改容器的内在状态,会使原本指向被移动元素的迭代器失效,也可能使其他迭代器失效,使用无效的迭代器是没有意义的,可能会导致和使用空指针相同的问题,所以使用迭代器时,需要特别留意哪些操作会使迭代器失效,使用无效迭代器会导致严重的运行错误。
算法
头文件:
<algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
<functional>中则定义了一些模板类,用以声明函数对象。
四大类算法:
非可变序列算法: 指不直接修改其所操作的容器内容的算法
可变序列算法: 指可以修改它们所操作的容器内容的算法
排序算法: 对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作
数值算法: 对容器内容进行数值计算
功能细分
查找算法:判断容器内是否包含莫个值
提供元素排序策略:
删除和替换算法:
排列组合算法: 提供计算给定集合按一定顺序的所以可能排列组合
算数算法:
生成和异变算法:
关系算法:
集合算法:
堆算法:
具体使用方法可以参照以下网址:
http://www.cplusplus.com/reference