标准模板库STL中常用的算法
1、算法概述
- 算法就是一个个函数模板, 大多数在< algorithm> 中定义
- STL中提供能在各种容器中通用的算法,比如查找,排序等
- 算法通过迭代器来操纵容器中的元素。许多算法可以对容器中的一个局部区间进行操作,因此需要两个参数,一个是起始元素的迭代器,一个是终止元素的后面一个元素的迭代器。比如,排序和查找。 也就是操作一个容器的局部。
- 有的算法返回一个迭代器。比如 find() 算法,在容器中查找一个元素,并返回一个指向该元素的迭代器
- 算法可以处理容器,也可以处理普通数组
2、算法举例
(1)使用下述函数模板:
template<class InIt, class T>
InIt find(InIt first, InIt last, const T& val);
- InIt 代表的就是迭代器。
- first 和 last 这两个参数都是容器的迭代器,它们给出了容器中的查找区间起点和终点[first,last)。区间的起点是位于查找范围之中的,终点不是。find在[first,last)查找等于val的元素。last并不在查找返回。
- val 要查找的元素。
- 用 == 运算符判断相等。
- 函数返回值是一个迭代器。如果找到,则该迭代器指向被找到的元素。如果找不到,则该迭代器等于last。
注意:find()函数模板一般来说实现查找功能,但是其究竟用来干什么取决于使用者。此模板来自于dev c++。 不同的编译器,可能模板有所差异。其时间复杂度为O(n)
(2)使用上述模板实例化出来的函数进行相关操作
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main(){//find算法示例
int array[10] = {10,20,30,40};
vector<int> v;
v.push_back(1);v.push_back(2);
v.push_back(3);v.push_back(4);
vector<int>::iterator p;
p = find(v.begin(),v.end(),3); // 在数组查找3
if( p != v.end())
cout << * p << endl; //能找到,输出3
p = find(v.begin(),v.end(),9);//查找9
if( p == v.end())
cout << "not found " << endl;//找不到没输出
p = find(v.begin()+1,v.end()-2,1);//整个容器:[1,2,3,4], 查找区间:[2,3),查找1
if( p != v.end())
cout << * p << endl; //此时迭代器终点指向3
int * pp = find( array,array+4,20);//数组名是迭代器
cout << * pp << endl;
}
/*输出:
3
not found
3
20
*/
3. STL中的“大”、“小”和“相等”
- 关联容器内部的元素是从小到大排序的
- 有些算法要求其操作的区间是从小到大排序的,称为“有序区间算法”
例:binary_search - 有些算法会对区间进行从小到大排序,称为“排序算法”
例: sort - 还有一些其他算法会用到“大”,“小”的概念
使用STL时,在缺省的情况下,以下三个说法等价:
- x比y小
- 表达式“x<y”为真
- y比x大
-
有时,“x和y相等”等价于“x==y为真”
例:在未排序的区间上进行的算法,如顺序查找find
… -
有时“x和y相等”等价于“x小于y和y小于x同时为假”
例:
有序区间算法,如binary_search
关联容关联容器自身的成员函数find
#include <iostream>
#include <algorithm>
using namespace std;
class A {
int v;
public:
A(int n):v(n) { }
bool operator < ( const A & a2) const
{
//必须为常量成员函数。 这样定义 < 的意义是,任何两个class A的对象,一个都不会小于另外一个。
cout << v << "<" << a2.v << "?" << endl;
return false;
}
bool operator ==(const A & a2) const
{
cout << v << "==" << a2.v << "?" << endl;
return v == a2.v;
}
};
int main()
{
A a [] =
{ A(1),A(2),A(3),A(4),A(5) };
cout << binary_search(a,a+4,A(9));
//折半查找
return 0;
}
解释:
binary_search() 算法的查找原理:使用<
比较
先比较9和3:12345的一半为的元素为3,所以先比较3和9, 3<9 成立吗? 使用小于号比较。此时不成立,于是在前一半中查找,前一半的数字为123,于是使用9和2比较,2<9 成立吗? 不成立,再向前一半查找,此时只剩下1了。 于是比较1<9 成立吗?不成立。 于是再比较9<1 吗? 仍然不成立。 于是输出1。
即:x<y 不成立 y< x不成立,那么认为x==y。