二分查找

      当一个数组需要用到查找方法时,可以遍历整个数组,找到相等的值返回下标,这种方法效率比较低。如果这个数组是有序的,我们可以使用二分查找(折半查找)。二分查找是将数组不断的分成两段,判断我们要找的数据与中值是否相等。

     如果我们有这样一个数组 int [] arr={0,10,20,30,40,50,60,70},使用二分查找找到60;

    我们首先要找到中值30与60对比,30与60 是不等的,并且60比30 大,所以我们在40与70之间的中值50 与60相比,50与60也是不等的,并且60比50大,所以,让60与70之间的中值60 与60是相等的,所以返回中值60的下标,代码如下:

   

	public static int binarySearch(int[] arr,int key){
		int max,min,mid;
		min=0;
		max=arr.length-1;
		mid=(max+min)>>1; //右移一位相当于除2运算。
		while(arr[mid]!=key){              //当中值与要找的数据不相等,进入循环
			if (key>arr[mid]) {        //如果数据比中值大
				min=mid+1;         //让最小下标放在中值后面,找较大的另一半数据
			}
			else if(key<arr[mid]){     //如果数据比中值小
				max=mid-1;         //让最大下标放在中值前面,找较小的另一半数据
			}
			if (max<min) {             //当最大下标比最小下标小时,说明数据不存在
				return -1;
			}
			mid=(max+min)>>1;
		}
		return mid;                       //当中值与要找的数据相等,说明数据找到,返回中值的下标。
	}
     所以我们也可以换一种方式写这段代码,当最小小标小于等于最大下标,说明数据存在,进入循环折半查找,反之,说明数据不存在,循环结束返回-1.

   

        public static int binarySearch(int[] arr,int key){
		int max,min,mid;
		min=0;
		max=arr.length-1;
		mid=(max+min)>>1;
		while(min<=max){
			mid=(max+min)>>1;
			if (key>arr[mid]) {
				min=mid+1;
			}
			else if(key<arr[mid]){
				max=mid-1;
			}
			else
				return mid;
		}
		return -1;
	}
     那么,如果给定一个有序的数组,如果往数组中插入一个元素还保证数组有序,那么元素的脚标位改如何获取?   

     当一个数组初始化完毕,数组的个数是固定的,没有办法在数组里面增加元素,但是我们是可以获取它的脚标位的。如果我们要插入的这个元素数组里面没有,我们要找到这个元素的插入点我们知道,当max<min 的时候确定了元素其实是不存在的,因为max移到了min 的前面还是没找到,此时min所指的位置其实就是插入点,因为min刚好大一位。所以我们让没找到元素时的返回值为min即可。所以上述代码,把return -1改成return min就可以解决这个问题了。

    Java也是有二分查找方法的,Array.binarySearch();是Java自带的二分查找方法,如果我们调用这个方法:

       能够找到数据的下标为6,如果数据不存在呢?

        我们看到,当数据不存在时,它的返回值成了负数,这个负数其实是这个数据的插入点减一。55在数组之中的插入点应该是6,但这个数据其实是不存在的,所以用负数表示不存在的含义,也就是-6,但是我们为了解决和0冲突的问题,所以就让插入点减一。(试想如果我们要查找-1,插入点应该是0,但是如果我们不减去一,那就和零冲突了)。总而言之,Java真是一个贴心的存在啊,,虽然Java给我们提供了方法,但是必要的知识我们还是应该知道的。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值