二分法查找

详解二分法查找

​ 首先,我们要明白二分法查找适用于一个有序的数组,在java的学习中,我们一般会先接触冒泡排序,使用冒泡排序对无序数组进行排序后再用二分查找去搜索目标数.

二分法查找原理

​ 针对一个有序数组,当我们需要搜索某一个目标数时,我可以一个一个进行遍历搜索,但是,这样会浪费太多计算机资源,并且效率较低,因此,我们需要一个更加高效的方式进行搜索.

​ 二分法查找是指将目标数与有序数组的中间数进行比较,如果中间数大于目标数,则说明目标数在中间数的前面,反之则在中间数后面,再以中间数的前半部(或者后半部)为一个新数组,取中间数与目标数判断,再取新数组再判断,如此循环下去后,直到中间数等于目标数,这样,目标数便找到了.

二分法查找演示

​ 如下图,针对{1,2,3,4,5,6,7,8,9}这样一个数组使用二分法查找8这个元素.

在这里插入图片描述

第一次查找:

​ 取{1,2,3,4,5,6,7,8,9}数组的中间数:5,与目标数8进行比较,8>5,说明目标数8位于{6,7,8,9}这个新数组内.

第二次查找:

​ 取{6,7,8,9}这个新数组的中间数:7(注意,由于只有4个数,我们取中间前一位的数作为中间数),与目标数8比较,发现8>7,说明目标数8位于{8,9}这个数组内.

第三次查找:

​ 取{8,9}这个数组的中间数:8,发现目标数8等于中间数,因此找到了.

几个需要关注的地方

  1. 一个含n个元素的数组(或者说一个长度为n的数组),n为奇数,最多需要((n-1)/2)次查找即可找到目标数,n为偶数最多需要(n/2)次查找即可找到目标数.
  2. 编写代码时注意循环终止条件为中间数等于目标数.

Java代码

class BinarySearch{
	public static void main(String[] args){
		//定义1个数组作为目标数组
		int[]arr = {1,2,3,11,5,6,7,8,9,10};
		//定义1个int变量作为查找的元素
		int i = 11;
		//调用方法,定义变量接收方法的返回值
		int s = binary(MaoP.mao(arr),i);
		//打印
		System.out.println("你查找的元素索引为:"+s);
	}
	//定义1个方法,使用二分法查询某个元素的索引
	static int binary(int[] arr1,int a){
		//定义1个int变量表示二分法中最大索引
		int maxIndex = arr1.length - 1;
		//定义1个int变量表示二分法中最小索引
		int minIndex = 0;
		//定义1个int变量表示二分法中的中间索引
		int halfIndex = minIndex+(maxIndex-minIndex)/2;
		//循环(一般来讲是死循环,但是当查询的元素不位于目标数组中时,会跳出循环)
		while(minIndex <= maxIndex){
			//如果中间索引位置的元素与目标值相等,则返回索引并退出方法
			if (arr1[halfIndex] == a){
				return halfIndex;
			//如果中间索引位置值小于目标值,则说明被查找元素位于中间索引位置右侧,最小索引等于中间索引加1
			}else if(arr1[halfIndex] < a){
				minIndex = halfIndex + 1;
			//如果中间索引位置值大于目标值,则说明被查找元素位于中间索引位置左侧,最大索引等于中间索引减1
			}else{
				maxIndex = halfIndex - 1;
			}
			//未找到,重新给中间索引赋值
			halfIndex = minIndex+(maxIndex-minIndex)/2;
		}
		//未找到返回-1
		return -1;
	}
}

拓展之二维数组的二分法查询

​ 有兴趣的读者可以看一下,如有错误还请谅解

class TwoDimensionalSearch {
	public static void main(String[] args){
	//定义需要查询的数
	int a = 1;
	/*
	定义一个二维数组.(每个一维数组的长度相同),
	每一行都按照从左到右递增的顺序排序,每一列
	都按照从上到下递增的顺序排序
	*/
	int[][] arr ={{1,2,3,4,5},
				 {6,7,8,9,10},
				 {11,12,13,14,15},
				 {16,17,18,19,20},
				 {21,22,23,24,25}};
	//调用方法
	Find(a,arr);
	}
	//定义1个方法查找二维数组中是否存在查询的数
    static int Find(int i, int [][] array) {
		//定义外层数组的最小,最大,中间索引
		int minIndex = 0;
		int maxIndex = array.length-1;
		int halfIndex = minIndex+(maxIndex-minIndex)/2;
		//定义内层数组的最小,最大,中间索引
		int min = 0;
		int max = array[0].length-1;
		int half = min+(max-min)/2;
		//外层循环,控制外层数组二分法查询
		while(minIndex <= maxIndex){
			//内层循环,控制内层数组二分法查询是否有被查询的数
			while(min <= max){
				//如果有,输出ok,跳出方法,返回0
				if (i == array[halfIndex][half]){
					System.out.println("查询到该数!");
					return 0;
				}else if (i > array[halfIndex][half]){
					min = half + 1;
				}else{
					max = half -1;
				}
				half = min+(max-min)/2;
			}
			//重新给内层数组的最小,最大,中间索引赋值,使得下次循环内层数组时,各个索引值为初始值
			min = 0;
			max = array[0].length-1;
			half = min+(max-min)/2;
			//如果未在当前内层数组查询到该数,则判断该数位于该内层数组后面的数组中
			if (i  > array[halfIndex][min]){
				minIndex = halfIndex + 1;
			//如果未在当前内层数组查询到该数,则判断该数位于该内层数组前面的数组中
			}else if (i  < array[halfIndex][max]){
				maxIndex = halfIndex - 1;
			}
			halfIndex = minIndex+(maxIndex-minIndex)/2;
		}
		//如果循环到最后都未找到,打印结果
		System.out.println("未查询到该数!");
		return -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值