循环控制_二分查找

二分查找思路:

1、  规定要查找的值K可能在数组arr内下标区间a,b

2、  计算区间a,b的中间点m

3、  若k<arr[m],将区间缩小为a,m,继续二分查找

4、  若k>arr[m],将区间缩小为m,b,继续二分查找

5、  若k==arr[m],则找到元素位于位置m

 

难点:边界控制

要注意的点:关于区间的选法

半开半闭区间方便进行操作

比如说:[a,b)+[b,c)=[a,c)是一个无交集,又不改变区间表达格式的操作

                   b-a=len([a,b))

                   [a,a)=>empty range

而:[a,b]+[b,c]却不等于[a,c],这中间叠加的交集,难以处理

因此我们选择的区间是[a,b),所以b表示的是数组最右边+1那个数,这样,整个待二分查找区间就包含了数组所有元素。

 

代码示例:

 

package com.sise.recursion;

public class BinarySearch {

	/*
	 * 查找某个元素在数组中的下标
	 * k:待查找元素
	 * 查到返回下标,查不到返回-1
	 */
	public int binarySearch(int[] arr,int k) {
		int a=0;
		int b=arr.length;
		//循环不变式
		//[a,b)是个有效区间,(a<=b)
		//k可能在区间内
		while(a<b){
			//(a+b)/2可能溢出
//			int m=(a+b)/2;
			int m=a+(b-a)/2;
			//a==b:m=a and m=b(m=b会越界,这样下标m不包含在区间内,要特殊处理,区间为空)
			//因此条件排除空区间
			//b==a+1:m=a(可以通过循环)
			//b==a+2:m=a+1(可以通过循环)
			
			
			
			if(k<arr[m]){
				//不能取b=m-1,因为是左闭右开区间,所以如果b取m-1的话,
				//m-1这个下标对应的数不在下一次查找的区间范围内,会被漏掉
//				b=m-1;
				b=m;
			}else if(k>arr[m]){
				//a是有效的下标,所以既然k>arr[m]
				//则k不等于arr[m],可以跳过
				a=m+1;
			}else{
				return m;
			}
		}
		return -1;
	}
	public static void main(String[] args) {
		BinarySearch bs=new BinarySearch();
		System.out.println(
				bs.binarySearch(new int[]{12,10,15,100},15));
		System.out.println(
				bs.binarySearch(new int[]{12,10,15,100},-2));
		System.out.println(
				bs.binarySearch(new int[]{12,10,15,100},101));
		System.out.println(
				bs.binarySearch(new int[]{12,10,15,100},13));
		System.out.println("------------");
		System.out.println(
				bs.binarySearch(new int[]{},13));
		System.out.println(
				bs.binarySearch(new int[]{12},13));
		System.out.println(
				bs.binarySearch(new int[]{13},13));
		System.out.println("----------");
		System.out.println(
				bs.binarySearch(new int[]{12,10},10));
		System.out.println(
				bs.binarySearch(new int[]{12,10},12));
	}

}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值