二分查找
实现查找指定数值在元素有序的数组中存储的位置(索引),返回该位置(索引)。
解题步骤:
- 定义3个用来记录索引值的变量,变量
min
记录当前范围最小索引值,初始值为0
;变量max
记录当前范围最大索引值,初始值为数组长度-1
;变量mid
记录当前当前范围最中间元素的索引值,初始值为(min+max) / 2
。 - 使用循环,判断当前范围下,最中间元素值与指定查找的数值是否相等:
若相等,结束循环,返回当前范围最中间元素的索引值mid
若不相等,根据比较结果,缩小查询范围为上一次查询范围的一般
中间元素值 比 要查询的数值大,说明要查询的数值在当前范围的最小索引位置与中间索引位置之间,此时,更新查询范围为:范围最大索引值 = 上一次中间索引位置 -1
;
中间元素值 比 要查询的数值小,说明要查询的数值在当前范围的最大索引位置与中间索引位置之间,此时,更新查询范围为:范围最小索引值 = 上一次中间索引位置 +1
;
在新的查询范围中,更新中间元素值的位置,再次使用最中间元素值与指定查找的数值是否相等。中间索引值 = (范围最小索引值 +范围最大索引值) / 2
;
非递归实现
#include <iostream>
using namespace std;
//二分查找法(折半查找法)
int halfSearch(int arr[],int size, int number){
int min = 0; //最小下标
int max = size-1; //最大下标
int mid = 0; //中间下标
while (min<max){
//没找到,更新范围继续找
mid = (min + max) / 2;
if (arr[mid]>number){ //number在mid的左边
max = mid - 1; //改变最大下标
}
else if (arr[mid] < number){ //number在mid的右边
min = mid + 1; //改变最小下标
}
else{
return mid;
}
}
return -1;
}
int main(int argc, char** argv)
{
int a[] = { 23, 34, 45, 56, 67, 78, 89 };
cout << "search 34, its index is:" << endl;
cout << halfSearch(a, 7, 34) << endl;
system("pause");
return 0;
}
运行结果:
递归实现
#include <iostream>
using namespace std;
int halfSearch(int min, int max, int a[],int k)
{
int mid = (min + max) / 2;
if (min <= max)
{
if (k > a[mid])
{
halfSearch(mid + 1, max, a, k);
}
else if (k < a[mid])
{
halfSearch(min, mid - 1, a, k);
}
else if (k == a[mid])
{
return mid;
}
}
else return -1;
}
int main()
{
int a[] = { 23, 34, 45, 56, 67, 78, 89 };
cout << "search 34, its index is:" << endl;
cout<<find(0, 6, a, 34)<<endl;
system("pause");
return 0;
}
运行结果:
以上内容来自:
- 解题思路与非递归实现:秋夜雨巷_查找-二分法查找(折半查找法)
- 递归实现:终极香蕉大菠萝_二分查找 递归实现