二分(折半)查找
二分查找是一种算法,其输入是一个有序的元素列表(必须是有序的),如果查找的元素包含在列表中,二分查找返回其位置,否则返回NULL
解题思路:
二分查找也称为折半查找,是最著名的查找算法,优点是算法简
单易实现,查找速度快,平均性能好,时间复杂度仅为 O(logn),缺
点是数据必须顺序存储且有序。
考点:
1、折半查找的实现。
2、时间复杂度。复杂度仅为log(N)
3、适用场景(数据必须顺序存储且有序)。
代码:
#include
using namespace std;
int main() {
int guess = 499; //猜测字符
int a[1000]; //注意这里的数组下标,即a[0]=1,a[1]=2……a[99]=100
int low = 0, mid, high = 999;
//初始化
cout << “1、初始化” << endl;
for (int i = 0; i < 1000; i++) {
a[i] = i;
}
// 二分查找
while (low <= high) { // 有等号
mid = (low + high) / 2;
if (a[mid] == guess) {
cout << “mid:” << mid << endl;
break;
}
else if (a[mid] < guess) low = mid + 1; // 有+1
else if (a[mid] > guess) high = mid - 1; // 有+1
}
system(“pause”);
return 0;
}
扩展:
mid = ((high - low)>>1) + low 和 mid = (low+high)/2 的区别是什么?
有重复数字如何处理?
C++ STL 中的 find 和 binary_search 如何实现?
1.用 mid=low+(high-low)/2 这种写法好,虽然数学上是一样的,
但是 mid=(low+high)/2 中的加法可能会发生溢出。
2.int binsearch_first(int arr[], int k, int n){
int l = -1, h = n;
while(l + 1 != h){
int m = (l + h) / 2;
if(k > arr[m]){
l = m;
}else{
h = m;
}
}
int p = h;
if(p >= n || arr[p] != k){
return -1;
}
return h;
}
3.binary_search:查找某个元素是否出现
a.函数模板:binary_search(arr[],arr[]+size , indx)
b.参数说明:
arr[]: 数组首地址
size:数组元素个数
indx:需要查找的值
#include
#include
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,结果为:”<<c<<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;
}
find() 函数本质上是一个模板函数,用于在指定范围内查找和目标元素值相等的第一个元素。
#include <iostream> // std::cout
#include <algorithm> // std::find
#include <vector> // std::vector
using namespace std;
int main() {
//find() 函数作用于普通数组
char stl[] ="http://c.biancheng.net/stl/";
//调用 find() 查找第一个字符 'c'
char * p = find(stl, stl + strlen(stl), 'c');
//判断是否查找成功
if (p != stl + strlen(stl)) {
cout << p << endl;
}
//find() 函数作用于容器
std::vector<int> myvector{ 10,20,30,40,50 };
std::vector<int>::iterator it;
it = find(myvector.begin(), myvector.end(), 30);
if (it != myvector.end())
cout << "查找成功:" << *it;
else
cout << "查找失败";
return 0;
}