二分查找法递归实现与非递归实现——java语言

1、二分查找法是我们常用的查找法,要使用它有一个前提条件:数组必须有序,递增或者递减;

2、二分查找的优点:比较次数较少、查找速度快、平均性能好;

3、二分查找的缺点:待查表为有序表,插入困难;由此延伸为顺序结构中,插入与删除比较困难

4、二分查找的思想:

步骤一:首先确定整个查找区间的中间位置mid = (end - start)/2;

步骤二用待查关键字值与中间位置的关键字值进行比较,若相等,则返回中间下标;

若不相等,有两种情况:

    若array[mid] > key:查找范围缩小为左半区域,具体表现为:statrt不变,end = mid - 1;

    若array[mid] < key:查找范围缩小为右半区域,具体表现为:end不变,start = mid + 1;

步骤三:对确定的缩小区域再进行折半公式,重复以上步骤!

注意的点:在使用if时一定要确定好是否还可以继续if的条件,那就是:start <= end,只有在这个条件底下,才可以查询!!!

5、来看非递归代码的实现:

public class BinSreach {
	public static void main(String[] args) {
		int arr[] = {2,4,6,7,8,9,10,17,19,20,34,78,89};
		int aimIndex = BinarySreach(arr, 19);
		System.out.println(aimIndex);
	}
	
	//一般方法
	public static int BinarySreach(int[] arr, int key) {
		//在这里提前判断一下数组是否为空,如果为空,那就没必要在查找了
		if(arr == null) {
			return -1;
		}
		//若不为空,则进行如下操作
		int start = 0;      //定义开始下标
		int end = arr.length - 1;        //定义末尾下标
		int mid = 0;        //定义中间下标
		
		//先使用中间值与关键字值进行比较
		if(arr[arr.length/2] == key) {
			return arr.length/2;
		}
		//如果中间值与关键字值不相等,进行一下查找。start <= end是一个非常重要的条件,只有在符合这个条件的前提下,才可以进行查找
		while(start <= end) {        
			//这也是一个相当重要的公式,用于在小范围内查找中见下标,所有的中间下标都是基于这个小范围来说的
			//它具体的值都是基于整个数组的顺序来说的,所以要在末尾加上start
			mid = (end - start)/2 + start;   
			if(arr[mid] > key) {         //当中间值大于关键字的情况
				end = mid - 1;           //缩小为作左边范围
			} else if(arr[mid] < key) {  //当中间值小于关键字的情况
			    start = mid + 1;         //缩小为右边范围
			} else{      //若是两个小范围都不符合以上两种情况,那就是在小范围内相等的情况了
				return mid;
			}
		}		
		return -1;	
	}
}

代码的每一行几乎都有注释,写的挺清楚的,哪里有漏洞,请大家多多指教呀~

结果如下:

6、使用递归方法实现:

在看代码之前,我想给大家说一个很重要的事情:在写递归的时候一定要考虑到这个递归结束的条件!!!

在看代码之前,我想给大家说一个很重要的事情:在写递归的时候一定要考虑到这个递归结束的条件!!!

在看代码之前,我想给大家说一个很重要的事情:在写递归的时候一定要考虑到这个递归结束的条件!!!

可能是自己的代码量太少了,所以在昨天尝试使用递归时,写完程序发现运行结果不对,首先是自己忘了将结果return一下。后来将关键字换为一个不在数组中的数字,发现下标标越界错误,原来是没有写结束的条件:start > end,希望大家引以为戒!

/**
 * @author 橙橙橙。
 * Date:2019.03.15
 * 题目:使用递归方式实现二分查找
 * 步骤:不断地使用中间查找法
 * 写完之后的问题:没有加return,导致结果输出错误
 */
public class BinSreach2 {
	public static void main(String[] args) {
	
		int arr[] = {2,4,6,7,8,9,10,17,19,20,34,78,89};
		int aimIndex = BinSreachOfRecursion(arr,0,arr.length-1,89);
		System.out.println(aimIndex);
	}

	public static int BinSreachOfRecursion(int[] arr, int start, int end,int key) {
		if(arr == null) {
			return -1;
		}
		//这个判断,必不可少,因为它就是递归种植的条件呀~
		if(start > end) {
			return -1;
		}
		int mid = (end - start)/2 + start;
		if(arr[mid] > key) {
			//在这个,一定要有return
			return BinSreachOfRecursion(arr, start, mid-1, key);
		} else if(arr[mid] < key) {
			//在这个,一定要有return
			return BinSreachOfRecursion(arr, mid+1, end, key);
		} else {
			return mid;
		}		
	}
}

由于在非递归查找时,已经写过详细过程,此处代码不再赘述;

结果:

二分查找告一段落,下回分解:老掉牙的快速排序~

生活就像一汪海洋,只有意志坚定的人,才可以走到彼岸!相信你也是个意志坚定的人~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值