《数组》--DAY1--二分查找
分治算法——二分查找(返回下标)
1.定义:在有序列表中,每次查找范围折半
- 列表若存在重复元素,返回下标不唯一
- 优点:比较次数少,速度快,性能好;缺点:要求列表有序
- 注意区分
while(left < right)还是while(left <= right);right=middle还是right=middle-1
2.实现原理
先取mid=(right+left)/2,比较target与array[mid]。若target<array[mid],令right=mid-1,重新取mid=(right+left)/2;若target>array[mid],令left=mid+1,重新取mid=(right+left)/2。依次不断地推下去,若left>right则查找失败

3.代码实现
-非递归
#include<iostream>
using namespace std;
int binarysearch(int arr[], int n, int target)
{
int left = 0, right = n - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (target > arr[mid]) left = mid + 1;
else if (target < arr[mid]) right = mid - 1;
else return mid;
}
return -1;
}
int main()
{
int target = 26;
int arr[10] = { 1,5,7,13,17,23,26,36,48,88 };
int ans = binarysearch(arr, 10, target);
printf("target对应数组下标为:%d", ans);
return 0;
}
- 注意mid一定是在while循环里面进行更新,这样left和right才能同时一起进行更新,若mid在函数外面则mid永远等于4,这样left只更新到4+1=5,left<right=9,mid永远无法进行更新,此时while进入死循环!!!
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
-递归实现
#include<iostream>
using namespace std;
int binarysearch(int arr[], int left,int right, int target)
{
if (left > right) return -1;
int mid = (left + right) / 2;
if (arr[mid] == target) return mid;
//若全部使用if语句,需要使用return有返回值,否则这一条语句会一直执行下去
/*if (target < arr[mid]) return binarysearch(arr, left, mid - 1, target);
if (target > arr[mid]) return binarysearch(arr, mid+1, right, target);*/
else if (target < arr[mid]) binarysearch(arr, left, mid - 1, target);
else if (target > arr[mid]) binarysearch(arr, mid + 1, right, target);
}
int main()
{
int target = 26;
int arr[10] = { 1,5,7,13,17,23,26,36,48,88 };
int ans = binarysearch(arr, 0, 9, target);
printf("target对应数组下标为:%d", ans);
return 0;
}
- 容易在if与else if语句出现未定义行的错误!
4.总结--二分查找核心总结
二分查找以有序列表为前提,通过折半缩小范围,实现O(log n)高效搜索。关键陷阱在于边界控制:循环条件(left ≤ right时有效区间需闭合)、指针更新(mid±1避免死循环),以及递归必须显式返回结果。非递归以O(1)空间碾压递归的隐式栈消耗,而重复元素导致下标不唯一需特殊处理。注意要是数组很长,left+right可能会溢出,可写成mid=left+(right-left)/2)!
浙公网安备 33010602011771号