二分查找算法

STL中的二分查找算法

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

binary_search 
lower_bound 
upper_bound

用binary_search进行二分查找(用法一)

在从小到大排好序的基本类型数组上进行二分查找 binary_search(数组名+n1,数组名+n2,值); n1和n2都是int类型的表达式,可以包含变量 如果n1=0,则 + n1可以不写

查找区间为下标范围为[n1,n2)的元素,下标为n2的元素不在查找区间内
在该区间内查找"等于"值”的元素,返回值为true(找到)或false(没找到)
"等于"的含义: a 等于 B <=> a < b和b < a都不成立

用binary_search进行二分查找(用法二)

在用自定义排序规则排好序的、元素为任意的T类型的数组中进行二分查找
binary_search(数组名+n1,数组名+n2,值,排序规则结构名());
n1和n2都是int类型的表达式,可以包含变量
如果n1=0,则 + n1可以不写
查找区间为下标范围为[n1,n2)的元素,下标为n2的元素不在查找区间内
在该区间内查找"等于"值的元素,返回值为true(找到)或false(没找到)
查找时的排序规则,必须和排序时的规则一致!
"等于"的含义: 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) {
    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
result:1

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

用binary_search进行二分查找(用法二)

    #include <iostream>
    #include <cstring>
    #include <algorithm> using namespace std; struct Student {
    char name[20]; int  id;  double gpa;
    };
    
    Student students [] = {
    {"Jack",112,3.4},{"Mary",102,3.8},{"Mary",117,3.9},
    {"Ala",333,3.5},{"Zero",101,4.0}};
    
    struct StudentRule1 { //按姓名从小到大排
    bool operator() (const Student & s1,const Student & s2) {
    if( stricmp(s1.name,s2.name) < 0)
    return true; return false;
    }
    };
    struct StudentRule2 { //按id从小到大排
    bool operator() (const Student & s1,const Student & s2) { return s1.id < s2.id;
    }
    };
    struct StudentRule3 {//按gpa从高到低排
    bool operator() (const Student & s1,const Student & s2) { return s1.gpa > s2.gpa;
    }
    };
    
    int main(){
    Student s; strcpy(s.name,"Mary"); s.id= 117;
    s.gpa = 0;
    int n = sizeof(students) / sizeof(Student); sort(students,students+n,StudentRule1()); //按姓名从小到大排
    cout << binary_search( students , students+n,s,
    StudentRule1()) << endl;
    strcpy(s.name,"Bob");
    cout << binary_search( students , students+n,s,
    StudentRule1()) << endl;
    sort(students,students+n,StudentRule2()); //按id从小到大排
    cout << binary_search( students , students+n,s,
    StudentRule2()) << endl;
    return 0;
    }

测试结果:
1
0
1

用lower_bound二分查找下界(用法一)

在对元素类型为T的从小到大排好序的基本类型的数组中进行查找
T * lower_bound(数组名+n1,数组名+n2,值);
返回一个指针 T * p;
*p 是查找区间里下标最小的,大于等于"值" 的元素。如果找不到,p指向下标为n2的元素

用lower_bound二分查找下界(用法二)

在元素为任意的T类型、按照自定义排序规则排好序的数组中进行查找
T * lower_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针 T * p;
*p 是查找区间里下标最小的,按自定义排序规则,可以排在"值"后面的元素。如果找不到,p指向下标为n2的元素

用upper_bound二分查找上界(用法一)
在元素类型为T的从小到大排好序的基本类型的数组中进行查找
T * upper_bound(数组名+n1,数组名+n2,值);
返回一个指针 T * p;
*p 是查找区间里下标最小的,大于"值"的元素。如果找不到,p指向下标为n2的元素

用upper_bound二分查找上界(用法二)

在元素为任意的T类型、按照自定义排序规则排好序的数组中进行查找
T * upper_bound(数组名+n1,数组名+n2,值,排序规则结构名());
返回一个指针 T * p;
*p 是查找区间里下标最小的,按自定义排序规则,必须排在"值"后面的元素。如果找不到,p指向下标为n2的元素

lower_bound,upper_bound用法示例

        #include <iostream>
        #include <cstring>
        #include <algorithm> using namespace std; struct Rule
        {
        bool operator()( const int & a1,const int & a2) {
        return a1%10 < a2%10;
        }
        };
        void Print(int a[],int size) {
        for(int i = 0;i < size;++i) { cout << a[i] << "," ;
        }
        cout << endl;
        }	29
        
        
        
        #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;		
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值