文章目录
1. STL的定义和基本概念
标准模板库
(standard template library)就是一些常用的数据结构(比如链表,数组,二叉树)和算法(排序,查找)的模板的集合。
STL的基本概念:
容器
:可以容纳各种数据类型的通用数据结构,是类模板。
迭代器
:可用于依次存取容器中的元素,类似指针。
算法
:用来操作容器中的元素和函数模板。
例如:
sort()
:对一个vector
中的数据进行排序;
find()
:搜索一个list
中的对象。
注意:算法本身与他们操作的数据类型无关,因此简单数组也可以使用算法。在C++里面一个简单的数组也可以被认为一个容器。
例如:
int array[100]
数组就是一个容器,而int *
类型的指针变量就可以作为迭代器,sort
算法可以作用于该容器上,对其进行排序。
sort(array, arrat + 70);//将前70个元素排序,array和array+70就是迭代器
2. 容器概述
定义:用于存放各种类型数据的数据结构,都是类模板,分为三种.
顺序容器:vector
(动态数组),deque
(双向队列),list
(双向链表);
关联容器:set
,multiset
,map
,multimap
;
容器适配器:stack
,queue
,priority_queue
。
2.1 顺序容器
2.1.1 vector
1)必须头文件<vector>
,#include<vector>
。动态数组。
2)元素在内存连续存放。随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳的性能(大部分是常数时间),在中间插入慢。
3)支持随机访问迭代器。
二维动态数组vector <vector<int> > v(3)
,v
有三个元素,每个元素都是vector<int>
。
2.1.2 deque
1)头文件<deque>
双向队列。
2)随机存取任何元素都能在常数时间完成(次于vetor
)。在两端增删元素具有较佳的性能(大部分是常数时间)。
3)有push_front
:将元素插入到容器的头部,pop_front
:删除头部元素。
2.1.3 list
1)头文件<list>
。双向链表。
2)元素在内存不连续存放。在任何位置增删元素都能在常数时间完成。
3)不支持随机存取。
4)只能使用双向迭代器,不支持大于/小于比较运算符,不支持下标访问[]
和随机移动(迭代器+2)。
2.2 关联容器
元素是排序的。
插入任何元素,都按相应的排序规则来确定其位置。
在查找是具有非常好的性能。
通常以平衡二叉树方式实现
2.2.1 set/multiset
头文件<set>
。set
不允许相同的元素。multiset
允许存在相同的元素。
2.2.2 map/multimap
2.3 容器适配器
1)stack
:头文件<stack>
:后进先出
2)queue
:头文件<queue>
:先进先出
3)priority_queue
:头文件<queue>
:最高优先级元素总是第一个出列
4)三个成员函数push
:添加一个元素。top
:返回栈顶部辉队头元素的引用。pop
:删除一个元素。
5)没有迭代器
6)STL中各种排序,查找,变序等算法不适用容器适配器
3. 成员函数
3.1 顺序容器和关联容器都有的成员函数
begin
:返回指向容器中第一个元素的迭代器。
end
:返回指向容器中最后一个元素后面的位置的迭代器。
rbegin
:返回指向容器中最后一个元素的迭代器。
rend
:返回指向容器中第一个元素前面的位置的迭代器。
3.2 顺序容器的常用成员函数
front
:返回容器中第一个元素的引用。
back
:返回容器中最后一个元素的引用。
push_back
:在容器的末尾增加新元素。
pop_back
删除容器末尾的元素。
4. 迭代器
用于指向顺序容器和关联容器中的元素。
用法与指针类似。
有const
和非const
两种
4.1 定义迭代器
定义的方法有两种:容器类名::iterator 变量名;
或者容器类名::const_iterator 变量名;
访问一个迭代器指向的元素:* 迭代器变量名
迭代器可以执行++
操作。
4.2 迭代器示例
#include<vector>
#include<iostream>
using namespace std;
int main(){
vector<int> v; //定义一个存放int元素的数组,一开始里面没有元素
v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);
vector<int>::const_iterator i;//常量迭代器,只能访问不能修改
for(i = v.begin(); i != v.end(); i++)
cout << *i << ',';
cout << endl;
vector<int>::reverse_iterator r;//反向迭代器
for(r = v.rbegin(); r != v.rend(); r++)
cout << *r << ',';
cout << endl;
vector<int>::iterator j;//非常量迭代器
for(j = v.begin(); j != v.end(); j++)
*j = 100;
for(i = v.begin();i != v.end(); i++)
cout << *i << ',';
cout << endl;
return 0;
}
4.3 不同容器的迭代器不一样
vector
和deque
容器的迭代器类别为随机访问;
list
,set/multiset
,map/multimap
容器的迭代器类别为双向;
stack
,queue
和priority_queue
不支持迭代器。
遍历vector
可以有以下几种做法(deque
亦然)
vector<int> v(100);//定义一个整型的vector,有100个数。
int i;
for(i = 0; i < v.size(); i++)// v.size() 代表v元素个数。
cout << v[i];//根据下标随机访问。
vector<int>::const_iterator ii;
for(ii = v.begin(); ii != v.end(); ii++)
cout << *ii;
for(ii = v.begin(); ii < v.end(); ii++)//随机迭代器可以使用小于号比较
cout << *ii;
//间隔一个输出
ii = v.begin();
while(ii < v.end()){
cout << *ii;
ii = ii + 2;//随机迭代器可以加
}
list<int> v;
list<int>::const)_iterator ii;
for(ii = v.begin(); ii != v.end(); ii++)
cout << *ii;
//举例两个错误的做法
//双向迭代器不支持<,list没有[]成员函数
for(ii = v.begin(); ii < v.end(); ii++)
cout << *ii;
for(ii = v.begin(); ii != v.end(); ii++)
cout << v[ii];
正确的遍历list
5. 算法简介
算法就是一个个函数模板,大多数在<algoritnm>
中定义。
算法可以处理容器,也可以处理普通数组。