基本思想
二分查找又叫折半查找,其基本思想是:将列表中间位置的元素与目标元素比较,如果两者相等,则查找成功;否则将列表从中间位置分开,分成前、后两个子列表,如果中间位置的元素大于目标元素,则进一步查找前一子列表,否则进一步查找后一子列表。重复以上过程,直到找到满足条件的元素,使查找成功;或子表为空,此时制定元素不在列表内部。
例如:
有序列列表:L=[1,4,8,9,12,63,79]
查找元素:T=8
第一步:比较L的中间元素9和目标元素8,9>8,子列表L=[1,4,8]
第二步:比较L的中间元素4和目标元素8,4<8,子列表L=[8]
第三步:比较L的中间元素8和目标元素8,8=8,找到目标元素在L中的位置
根据上述操作,可以给出二分查找的一个简明代码,如下所示:
int BinarySearch(int L[],int target,int left,int right)
{
while(right>=left)
{
int mid = left + (right - left)/2;
if(L[mid]==target)
return mid;
else if (L[mid]<target)
{
left = mid+1;
}
else
{
right = mid-1;
}
return TARGET_NOT_FOUND;
}
}
注意的细节
(1) 数据范围:整数的范围为-231~231-1,二分查找在求中间位置时,如果使用int mid = (left+right)/2
的形式,则对于较大的left和right,有可能向加后超过整型的表示范围,得到错误的计算结果,因此应使用int mid = left + (right - left)/2
的形式。
(2) 边界条件:边界确定涉及二分查找算法中的判断和赋值,边界必须遵循一致的区间规则,序列及其子序列的mid和right都要表示统一的开闭区间。
LeetCode 二分查找
题目描述
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例1
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例2
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
代码
int search(int* nums, int numsSize, int target) {
int left=0;int right=numsSize-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(target==nums[mid]) return mid;
else if(target<nums[mid])
{
right=mid-1;
}
else
{
left=mid+1;
}
}
return -1;
}