欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STL中的二分查找算法

程序员文章站 2022-03-14 10:00:21
...

STL中的二分查找算法

STL提供在排好序的数组上进行二分查找的算法

binary_search

lower_bound

upper_bound

用binary_search进行二分查找

1.binary_search(数组名+n1,数组名+n2,值);

从小到大排好序的基本类型数组上进行二分查找。查找区间为下标范围为[n1,n2)的元素,在该区间内查找"等于"值”的元素,返回值为true(找到)或false(没找到)

注:"等于"的含义:a 等于 B <=> a < b和b < a都不成立

2.binary_search(数组名+n1,数组名+n2,值,排序规则结构名());

注:查找时的排序规则必须和排序时的规则一致!

"等于"的含义:a 等于 b <=> "a必须在b前面"和"b必须在a前面"都不成立

例:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

struct Rule //按个位数从小到大排
{
       bool operator()( const int & a1,const int & a2) const {
              return a1%10 < a2%10;
       }
};

void Print(int a[],int size) {
       for(int i = 0;i < size;++i) {
               cout << a[i] << "," ;
       }
       cout << endl;
}

int main() {
        int a[] = { 12,45,3,98,21,7};
        sort(a,a+6);
        Print(a,6);
        cout <<"result:"<< binary_search(a,a+6,12) << endl;
        cout <<"result:"<< binary_search(a,a+6,77) << endl;
        sort(a,a+6,Rule()); //按个位数从小到大排
        Print(a,6);
        cout <<"result:"<< binary_search(a,a+6,7) << endl;
        cout <<"result:"<< binary_search(a,a+6,8,Rule()) << endl;
        return 0;
}

输出:
3,7,12,21,45,98,
result:1
result:0
21,12,3,45,7,98,
result:0
//数组里面有7不代表你能查得到,因为使用的是二分查找。之所以明明有7却找不到的原因是查找时的排序规则和排序时的规则不一致,这导致默认数组当初是从小到大排的,然而这里数组是从个位从小到大排的。这导致查找的结果是毫无意义的
result:1
//明明没有8却找到了8,这里是因为二分查找的等于含义比较微妙。你把98和8比较,排序规则是从个位数从小到大排。"98必须在8前面"和"8必须在98前面"都不成立。所以认为98=8,找到8。
用lower_bound二分查找下界

1.T * lower_bound(数组名+n1,数组名+n2,值);

在对元素类型为T的从小到大排好序的基本类型的数组中进行查找

返回一个指针 T * p;*p 是查找区间里下标最小的大于等于"值" 的元素。如果找不到p指向下标为n2的元素

2.T * lower_bound(数组名+n1,数组名+n2,值,排序规则结构名());

在元素为任意的T类型,按照自定义排序规则排好序的数组中进行查找

返回一个指针 T * p;*p 是查找区间里下标最小的按自定义排序规则,可以(理解为大于等于)排在"值"后面的元素。如果找不到p指向下标为n2的元素

用upper_bound二分查找上界

1.T * upper_bound(数组名+n1,数组名+n2,值);

在元素类型为T的从小到大排好序的基本类型的数组中进行查找

返回一个指针 T * p;*p 是查找区间里下标最小的大于"值"的元素。如果找不到p指向下标为n2的元素

2.T * upper_bound(数组名+n1,数组名+n2,值,排序规则结构名());

在元素为任意的T类型,按照自定义排序规则排好序的数组中进行查找

返回一个指针 T * p;*p 是查找区间里下标最小的按自定义排序规则必须排在"值"后面的元素。如果找不到p指向下标为n2的元素

用法示例:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Rule
{
       bool operator()( const int & a1,const int & a2) const {
              return a1%10 < a2%10;
       }
};

void Print(int a[],int size) {
       for(int i = 0;i < size;++i) {
               cout << a[i] << "," ;
       }
       cout << endl;
}

#define NUM 7
int main()
{
      int a[NUM] = { 12,5,3,5,98,21,7};
      sort(a,a+NUM);
      Print(a,NUM); // => 3,5,5,7,12,21,98,
      int * p = lower_bound(a,a+NUM,5);
      cout << *p << "," << p-a << endl; //=> 5,1
      p = upper_bound(a,a+NUM,5);
      cout << *p << endl; //=>7
      cout << * upper_bound(a,a+NUM,13) << endl; //=>21
      
      sort(a,a+NUM,Rule());
      Print(a,NUM); //=>21,12,3,5,5,7,98,
      cout << * lower_bound(a,a+NUM,16,Rule()) << endl; // => 7
      cout << lower_bound(a,a+NUM,25,Rule()) - a<< endl; // => 3
      cout << upper_bound(a,a+NUM,18,Rule()) - a << endl; // => 7
      if( upper_bound(a,a+NUM,18,Rule()) == a+NUM)
      cout << "not found" << endl; //=> not found
      cout << * upper_bound(a,a+NUM,5,Rule()) << endl; // =>7
      cout << * upper_bound(a,a+NUM,4,Rule()) << endl; // =>5
      return 0;
}
相关标签: STL入门 c++