数据结构-二分查找法-java实现
一、基本思想
二分查找是远近闻名的查找大法之一,其主要的思路和我们小时候经常玩的猜数字是一样的,就比如给你一组数字[1,2,3,4,5,6,7,8,9],
要猜到的数字是5
你第一次猜了2,小伙伴告诉你小了,然后你就会从[2,3,4,5,6,7,8,9]中在猜一个数字
你第二次踩了6,小伙伴告诉你大了,然后你就会从[2,3,4,5]中猜一个数字
你第三次猜了3,小伙伴告诉你小了,然后你就从[4,5]中猜一个数字
你第四次猜了5,小伙伴告诉你猜对了,你真棒!
以上就是二分查找法的简要理念,你猜中数字总共用了四次机会。
但是你回家晚上睡不着觉就琢磨,我怎么才能更快的猜中数字呢,然后你就想到了,每次不再随机的选择猜的数字,而是每次都选最中间的那个数字,因为这样可以最快的缩小范围到一半,然后就有了下面这种猜测
你第一次猜了最中间位置的数字5,小伙伴告诉你猜对了,你真棒!
这次的猜测你只使用了1次机会,晚上你回家躺在床上又想,因为要查找的数字就是最中间的5,所以有随机性,所以你试了以下查找6,就有了以下的猜测
你第一次猜了最中间的数字5,小伙伴说小了,你就把范围缩在了[6,7,8,9]中在选择
你第二次猜了最中间的数字7,小伙伴说打了,你就把范围缩在了[6]在选择
你第三次猜了最中间的数字6,小伙伴说猜对了,你真棒!
以上就是真正的二分查找法的思路,就这样你发明了二分查找法,想要用代码写出来,你就想到了接下来的思路
二、代码实现
1、递归法
因为每次查找都是去寻找中间位置的数值比较,根据比较结果缩小范围或者得出结果,这个过程是重复的,所以可以使用递归进行实现。递归的结束条件就是当左指针不小于右指针的时候终止递归。
代码如下:
public int binarySearch(int[] arr, int left, int right, int value) {
// 当左指针不小于右指针时,说明未找到结果
if (left >= right){
return -1;
}
// 最中间位置的索引
int binary = (left + right) / 2;
// 判断大小,缩小范围
if (arr[binary] > value) {
// 大于查找值,结果在左边,将右指针移动到中间位置
binarySearch(arr, left, binary, value);
} else if (arr[binary] < value) {
// 小于查找值,结果在右边,将左指针移动到中间位置
binarySearch(arr, binary, right, value);
}
// 返回结果
return binary;
}
2、循环求解
你不喜欢使用递归,你觉得不必要,你就像使用一个循环,不断地迭代求解,所以有了接下来地代码,两者地思路相同,只是实现方法不同。
public int binarySearch2(int[] arr, int value){
// 维护两个指针
int left = 0;
int right = arr.length;
// 结果初始化-1
int ans = -1;
// 循环,循环条件左指针小于右指针
while (left < right){
// 中间位置地索引值
int midIndex = (left+right)/2;
// 大于查找值,右指针左移
if (arr[midIndex] > value){
right = midIndex;
// 小于查找值,左指针右移
}else if (arr[midIndex] < value){
left = midIndex;
}else {
// 相等,赋值结果,终止循环
ans = midIndex;
break;
}
}
// 返回结果
return ans;
}