首先来简单介绍一下STL是什么:STL全称“ standard template library”,中文名为“标准模板库”,可以这样说,STL就是“容器”,”算法“和其它一些组件的集合,目前它是c++中的一部分,用c++编写程序时可以直接使用。
STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)六个部分。
在C++标准中,STL被组织为下面的17个头文件:<algorithm>、<deque>、<functional>、<iterator>、<array>、<vector>、<list>、<forward_list>、<map>、<unordered_map>、<memory>、<numeric>、<queue>、<set>、<unordered_set>、<stack>和<utility>。
其中容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成。
算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。
那么接下来要要探讨的 排序与检索 将使用到STL中的sort函数以及二分查找,其添加在<algorithm>头文件中
下面介绍一下sort函数和二分查找
sort函数
时间复杂度:n*log(n)
实现原理:sort和c中的qsort有所区别,sort并不是简单的快速排序,它对普通的快速排序进行了优化,此外,它还结合了插入排序和推排序。系统会根据你的数据形式和数据量自动选择合适的排序方法,这并不是说它每次排序只选择一种方法,它是在一次完整排序中不同的情况选用不同方法,比如给一个数据量较大的数组排序,开始采用快速排序,分段递归,分段之后每一段的数据量达到一个较小值后它就不继续往下递归,而是选择插入排序,如果递归的太深,他会选择推排序。
形式:sort(数组首地址,数组首地址加数组长度,(自定义比较函数)) //自定义比较函数没有特殊排序要求可不写,sort函数默认排序方法为升序
第一种(只有前面两项的)
int a[5]={2,0,5,3,1};
sort(a,a+5);//简单的升序排列
for(int i=0;i<10;i++)
cout <<a[i]<<endl;
第二种(有自定义比较函数)//比如我想降序
bool cmp(int a, int b)
{
return a>b;
}
int a[5]={2,0,5,3,1};
sort(a,a+5,cmp);//注意cmp为bool函数名
for(int i=0;i<10;i++)
cout <<a[i]<<endl;
其实,我们完全可以偷懒不定义cmp这个函数名,因为在标准库当中有现成的,还记得我上面提到的算法的头文件吗,对,就是其中的functional头文件,它提供了一堆基于模板的比较函数对象,比如equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>,有兴趣的童鞋可以多加了解,那么在此,我们只需用到greater和less,形式如下
less<数据类型>() //从小到大排序 sort(a,a+5,less<int>());
greater<数据类型>() //从大到小排序 sort(a,a+5,greater<int>()); //注意在其它比如结构体中不适用
sort 的用途可不止是上面简单的排序那么low,其实我们可以对其进行扩展,那就看你对第三个参数cmp怎么使用了,sort不止应用于数组,其对结构体,类一样适用。
结构体排序
Student Stu[100];
bool cmp(Student a,Student b)
{
return a,id>b,id; //按学号降序排列
}
sort (Stu,Stu+100,cmp);
类
struct Less
{
bool operator()(const Student& s1, const Student& s2)
{
return s1.id>s2.id; //降序排列
}
};
sort(sutVector.begin(),stuVector.end(),Less()); //第四种 声明比较类用的比较少,了解即可
二分查找
头文件<algorithm>
1, binary_search:查找某个元素是否出现
形式:binary_search(arr[]),arr[]+size,index)
2, lower_bound:查找第一个大于或等于某个元素的位置 //前闭后开区间进行二分查找,返回的是地址 ,下同
形式:lower_bound(arr[],arr[]+size,index)
举例:
一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标,则
/*注意因为返回值是一个指针,所以减去数组的指针就是int变量了*/
pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。
pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。
pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。
e.注意:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!
返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置
3,upper_bounder:查找第一个大于某个元素的位置
形式:upper_bound(arr[],arr[]+size,index)
函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置。例如:一个数组number序列1,2,2,4.upper_bound(2)后,返回的位置是3(下标)也就是4所在的位置,同样,如果插入元素大于数组中全部元素,返回的是last。(注意:数组下标越界), 返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置 。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a[100]= {4,10,11,30,69,70,96,100};
int b=binary_search(a,a+9,4); //查找成功,返回1
cout<<"在数组中查找元素4,结果为:" <<b<<endl;
int c=binary_search(a,a+9,40);//查找失败,返回0
cout<<"在数组中查找元素40,结果为:" <<b<<endl;
int d=lower_bound(a,a+9,10)-a;
cout<<"在数组中查找第一个大于等于10的元素位置,结果为:" <<d<<endl;
int e=lower_bound(a,a+9,101)-a;
cout<<"在数组中查找第一个大于等于101的元素位置,结果为:" <<e<<endl;
int f=upper_bound(a,a+9,10)-a;
cout<<"在数组中查找第一个大于10的元素位置,结果为:" <<f<<endl;
int g=upper_bound(a,a+9,101)-a;
cout<<"在数组中查找第一个大于101的元素位置,结果为:" <<g<<endl;
}