查找方式有很多 顺序查找,逆序查找......
无非是 遍历数组中的所有成员 来找到所要的target 其时间复杂度为O(n)
那么 有没有更简单的查找方式呢?
二分查找 便是其中一个效率极好的算法
想象一个数组 数组的长度为 Length (此法使用左闭右闭的区间,且数组元素有序)
令 Left = 0 即数组的起始位置,Right = Length - 1 即数组的末位置 Mid = (Left +Right) / 2;
如果说 target > a[Mid] 即 target 大于 数组的中间元素值 那么 将 Mid+1 的值赋给 Left
为什么是 Mid+1 而不是 Mid 呢?原因是 a [Mid] 在跟target 作比较时就预示了接下来不需要
再将 a [Mid] 放入查找范围内 因此将 Mid+1赋给 Left
即对半分割了查找范围 Mid 也顺势改为( Left + Right ) / 2;由此一直进行下去 直到找到target值
或者 Left > Right (理论上 Left 一定大于 Right,因此当 Left > Right 时循环结束)
代码如下:
#include<iostream>
using namespace std;
int main()
{
int a[10];
for (int i = 0; i <= 9; i++) {
cout << "No:" << i + 1<<" ";
cin >> a[i];
}
int Mid, Left, Right, target;
cout << "Please input the target:";
cin >> target;
Left = 0; Right = 9;
while (Left <= Right) {
Mid = (Left + Right) / 2;
if (target == a[Mid]) {
cout << "Founded!";
return 0;
}
if (target > a[Mid]) {
Left = Mid + 1;
}
else
Right = Mid - 1;
}
cout << "Not found!";
return 0;
}
分析出 这里可以用到 递归 + 二分法 代码如下:
#include<iostream>
using namespace std;
int search(int Left, int Right,int target,int a[]);
int main() {
int target,a[10],Left,Right;
Left = 0; Right = 9;
for (int i = 0; i <= 9; i++) {
cin >> a[i];
}
cout << "Please input the target:";
cin >> target;
search(Left, Right, target,a);
return 0;
}
int search(int Left, int Right,int target, int a[]) {
if (Left > Right) {
cout << "Not found!";
return 0;
}
int Mid = (Left + Right) / 2;
if (target == a[Mid]) {
cout << "Founded!";
return 0;
}
else if (target > a[Mid]) {
return search(Mid + 1, Right, target, a);
}
else
return search(Left, Mid - 1, target, a);
}
时间复杂度也为 O(n).