算法(四)二分法查询

二分法讲解:

二分法的核心便是不断的缩小区间。要求的数大于底边则向上收缩区间,反之则向下。 以下是两个简单的案例来帮助大家理解和应用。基本上所有有序的数组都能够使用二分法写出想要的功能。


import java.util.Arrays;

public class Demo1 {
	public static void main(String[] args) {
		//初始化一个静态数组
		int [] values={3,72,8,5,9,150,27,85,94,66,21,45};
		//排序数组,二分法查找的前提数组是有序的(按小到大,从左往右排)
		Arrays.sort(values);
		System.out.println(Arrays.toString(values));
		//指定要查找的数
		int value=8;
		//查找数的下标
		int index=new Demo1().dichotomy(values, value);
		//System.out.println("你要查找的数在数组中的下标为:"+index);
		
	}
	/*
	 * 参数values,查询数组。参数value,要查询的值。
	 */
	 private int dichotomy(int [] values,int value) {
		 //变量base=底边
		int base=0;
		//变量top=顶边
		int top=values.length-1;
		while(base<=top){
			//middle=中间
			int middle=(top+base)/2;
			System.out.println("此次循环中间的数为:"+values[middle]+",下标为:"+middle);
			//查询到了就返回下标
			if(value==values[middle]){
					return middle;
			}
			//如果要查询的数比现在中间的数小,那么顶边=middle-1;
			if(value<values[middle]){
				top=middle-1;
			}
			//如果要查询的数比现在中间的数小,那么底边=middle+1;
			if(value>values[middle]){
				base=middle+1;
			}
		}
		//没找的返回-1
		return -1;
	}
}

结果如下:

实例问题

2. 获取数组最大值和最小值操作:利用Java的Math类的random()方法,编写函数得到0到n之间的随机数,n是参数。并找出产生50个这样的随机数中最大的、最小的数,并统计其中>=60的有多少个。

提示:使用 int num=(int)(n*Math.random());获取随机数。(题目出自http://www.sxt.cn/Java_jQuery_in_action/seven-task.html

以下是本人提供的优化解法:

public class Demo3 {
	public static void main(String[] args) {
		Demo3 d3= new Demo3();
		Scanner input=new Scanner(System.in);
		System.out.print("请输入准备生成多少个随机数:");
		int numbers=input.nextInt();
		System.out.print("请输入生成随机数的最大范围:");
		int maxRange=input.nextInt();
		
		int values[]=d3.initialize(numbers, maxRange);
		//排序数组
		Arrays.sort(values);
		System.out.println(Arrays.toString(values));
		//输出最大
		System.out.println("最大随机数:"+values[values.length-1]);
		//输出最小
		System.out.println("最小随机数:"+values[0]);
		//输出大于60
		int index=d3.greaterToValue(values, 60);
		System.out.println("数组中大于60的数:");
		//输出下标
		System.out.println("大于60的下标为:"+index);
		if(index==-1){
			return;
		}
		for (int i = index,j=0; i < values.length; i++,j++) {
			if(j%10==0){
				System.out.print("\n");
			}
			System.out.print(values[i]+"  ");
			
		}
	}
	//初始化数组
	private int[] initialize(int nums,int maxRange){
		int values[]=new int[nums];
		for (int i = 0; i < values.length-1; i++) {
			values[i]=(int)(Math.random()*maxRange);
		}
		return values;
	}
	//二分法查询大于60的数
	private int greaterToValue(int [] values,int value){
		//底边
		int base=0;
		int middle=0;
		//顶边
		int top=values.length-1;
		while(base<=top){
			//中间的数
			System.out.println("base:"+base+"|top:"+top);
			 middle=(base+top)/2;
			//middle左边一个小于60&&middle大于等于60跳出循环,返回下标
			if(values[middle-1]<value&&values[middle]>=value){
				return middle;
			}
			//middle大于等于60,顶边界限为middle-1
			if(value<=values[middle]){
				 top=middle-1;
			}
			//middle小于60,底部界限为middle+1
			if(value>values[middle]){
				base=middle+1;
			}
		}
		
		return -1;
	}
}

运行结果:

查询一个两百的数组仅仅只需要6次循环,效率可观。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值