算法入门—二分查找

备战蓝桥杯与csp — 二分查找


α. 时间复杂度分析

二分查找的前提是数组是有序的(所以经常配合sort函数使用),首先找到数组中间的值(将数组分成左右两部分),比较一下要查找的数,大了就使用左边的数组,小了使用右边的数组,接着重复上面的操作,找到或者当左边右边重合之后停止查找.
二分查找每一次都排除了1/2的数据,我们假设T次之后出现结果(m 条数据)
那么存在m / 2^T = 1
T = log(m)

时间复杂度为log(n)

β. 二分查找x的位置

#include <bits/stdc++.h>

#define ll long long
using namespace std;
ll a[11] = {4, 5, 7, 11, 23, 34, 45, 65, 89, 101}; // 默认升序排列

ll binary_sea(ll num, ll left, ll right) {
    while (left <= right) {
        ll mid = (left + right) / 2;
        if (a[mid] == num) return mid;
        else if (a[mid] > num) right = mid - 1;
        else left = mid + 1;
    }
    return -1; // 查询不到返回-1
}

int main() {
    printf("%lld", binary_sea(34, 0, 9)); // 5
    return 0;
}

γ. 调用库函数

stl 中提供了一些查找函数,我们可以直接调用,而无需再写一个函数,但思想还是需要掌握的~

γ1. binary_search

binary_search(beg,end,val)
beg : 查找开始的位置,左界
end: 查找结束的位置,右界
val: 需要查找的数据

γ2. lower_bound

lower_bound(beg,end,val)
返回第一个大于等于val的位置用法和binary_search一致

γ3. lower_bound

upper_bound(beg,end,val)
返回第一个大于val的位置用法和binary_search一致

#include <bits/stdc++.h>

#define ll long long
using namespace std;
vector<ll> v = {12,3,45,67,78,8,9,0,46};

int main() {
    sort(v.begin(),v.end()); //升序排序
    cout<<(int)binary_search(v.begin(),v.end(),34)<<endl; // 0 未找到
    cout<<(int)binary_search(v.begin(),v.end(),46)<<endl; // 1 找到了
    cout<<lower_bound(v.begin(),v.end(),46)-v.begin()<<endl; // 6
    cout<<upper_bound(v.begin(),v.end(),46)-v.begin()<<endl; // 7
    return 0;
}

posted @ 2020-12-03 11:03  沃特艾文儿  阅读(9)  评论(0)    收藏  举报  来源