前言
C++中已经实现了数据结构中的很多容器和算法,它们构成标准C++库的子集,即标准模板类库(Standard Template Library,STL)。
一、STL?
STL是一个功能强大的基于模板的容器库,通过直接使用这些现成的标准化组件可以大大提高算法设计的效率和可靠性。
STL主要由container(容器),algorithm(算法)和iterator(迭代器)三大部分构成,容器用于存放数据对象(元素),算法用于操作容器中的数据对象。简单理解就是:容器就是装东西用的,而算法就是处理容器里面的东西,而迭代器就是用来呈现这些东西的工具。
二、STL三大件
1.容器
简单来说STL容器就是一种数据结构,如:链表,栈和队列等,为了避免每次使用这些数据结构都要写冗杂的代码,于是在STL中已经实现好了,在算法设计可以直接使用它们。
数据结构 | 说明 | 实现头文件 |
向量(vector) | 连续存储元素,底层数据结构为数组,支持快速随机访问 | <vector> |
字符串(string) | 字符串处理容器 | <string> |
双端队列(deque) | 连续存储的指向不同元素的指针所组成的数组。底层数据结构为一个中央控制器和多个缓冲区,支持首尾元素(中间不能)快速增删,也支持随机访问 | <deque> |
链表 (list) | 由结点组成的链表,每个结点包含着一个元素。底层数据结构为双向链表,支持结点的快速增删。 | <list> |
栈 (stack) | 后进先出的序列。底层一般用deque(默认)或者list实现。 | <stack> |
队列 (queue) | 先进先出的序列。底层一般用deque(默认)或者list实现 | <queue> |
优先队列 (priority_queue) | 元素的进出队顺序由某个谓词或者关系函数决定的一种队列。底层数据结构一般为vector(默认)或者deque。 | <queue> |
集合(set)/多重集合(multiset) | 由结点组成的红黑树,每个结点都包含着一个元素,set中的所有元素有序但不重复,multiset中的所有关键字有序但可重复。 | <set> |
映射(map)/多重映射(multimap) | 由(关键字,值)对组成的集合,底层数据结构为红黑树,map中的所有关键字有序但不重复,multimap中的所有关键字有序但可以重复。 | <map> |
2.算法
STL算法是用来操作容器中数据的模板函数,STL提供了大约100个实现算法的模板函数。例如:排序算法sort(),不仅可以对内置数据类型的数据排序(如int类型)排序,也可以对自定义的结构体数据排序,甚至可以根据程序员需要按照指定的递增或者递减排序。
总的来说就是,对于一些基本算法,程序员不需要再自己耗费时间和精力写代码,只需要根据实际情况直接调用即可。
#include<iostream>
#include<iomanip> //setw函数头文件
#include<algorithm> //sort函数头文件
using namespace std;
int main(){
int a[10]={3,1,6,8,5,9,7,4,0,2};
cout<<"排序前:";
for(int i=0;i<10;i++)
cout<<setw(3)<<a[i];
cout<<endl;
cout<<"排序后:";
sort(a,a+10);
for(int i=0;i<10;i++)
cout<<setw(3)<<a[i];
cout<<endl;
}
3.迭代器
简单地说,STL迭代器用于访问容器中的数据对象。每个容器都有自己的迭代器,只有容器自己知道如何访问自己的元素。
换一种简单的方式理解就是,迭代器其实就像是C/C++里的指针变量,这个指针指向对应的容器,++运算符用来递增迭代器,指向下一个数据对象。如果迭代器到达容器最后一个元素后面,则迭代器变成一个特殊值,或者理解成指针变成了NULL或未初始化的指针。
常用的迭代器:
iterator:指向容器中存放元素的迭代器,用于正向遍历容器中的元素。
const_iterator: 指向容器中存放元素的常量迭代器,只能读取容器中的元素。
reverse_iterator:指向容器中存放元素的反向迭代器,用于反向遍历容器中的元素。
const_reverse_iterator:指向容器中存放元素的常量反向迭代器,只能读取容器中的元素。
迭代器的常用运算:
++:正向移动迭代器。
--:反向移动迭代器。
*:返回迭代器所指元素值。
#include<iostream>
#include<algorithm> //sort函数头文件
#include<vector> //vector头文件
using namespace std;
int main(){
vector<int> myv;
myv.push_back(1);
myv.push_back(2);
myv.push_back(3);
vector<int>::iterator it; //定义正向迭代器it
for(it=myv.begin();it!=myv.end();it++) //从头到尾遍历所有元素
cout<<*it<<" "; //输出:1 2 3
cout<<endl;
vector<int>::reverse_iterator rit; //定义反向迭代器rit
for(rit=myv.rbegin();rit!=myv.rend();rit++) //从尾到头遍历所有元素
cout<<*rit<<" "; //输出:3 2 1
cout<<endl;
}