查找算法---二分查找(递归方式)_对从大到小顺序的数据进行二分查找,并要求使用递归函数实现该二分查找,如果找到则-程序员宅基地

技术标签: 算法  java  二分查找递归方式  二分查找  二分法  

二分查找

前提条件

我们的二分查找必须是在有序数组中查找

无论是从小到大还是从大到小

题目

请对一个有序数组进行二分查找{1, 8,10,89,1000,1234},输入一个数
看看该数组是否在此数,姐出下标,如果没有就提示没有这个数”。

思路

我们这次的二分查找会用到递归的思想,当然也有非递归的方式,我是分开来学习了

1.首先确定数组的中间下标mid mid = (left+ right)/2

2.让需要查找的数findValue和我们的arr[mid]比较

​ 如果findValue>arr[mid],往右边递归

​ 如果findValue<arr[mid],向左边递归查找

​ 如果正好找到就返回

那我们的递归出口(结束条件)是什么

1.找到了,直接返回退出了

2.递归万整个数组,没有找到findValue,也需要结束递归时,当我们的left>right就代表要结束了

代码

//二分查找
//@author 王
public class BinarySearch {
    

	public static void main(String[] args) {
    
		// TODO Auto-generated method stub
		int arr[] = {
    1,8,10,89,1000,1234};//必须是有序数组
		int resultIndex = binarySearch(arr, 0, arr.length -1, 1234);
		System.out.println(resultIndex);
	}
	/**
	 * 
	 * @param arr			数组
	 * @param left			左边索引
	 * @param right			右边索引
	 * @param findValue		需要找的数字,找到返回下标,未找到返回-1
	 * @return
	 */
	//二分查找算法
	public static int binarySearch(int[] arr,int left,int right,int findValue) {
    
		int mid = (left+right)/2;
		int midValue = arr[mid];
		
		if(findValue >midValue){
    
			//向右递归
			return binarySearch(arr, mid+1, right, findValue);
		}else if(findValue < midValue){
    
			//向左递归
			return binarySearch(arr, left, mid-1, findValue);
		}else{
    
			return mid;
		}
	}

}

我们很容易发现这其中的问题,我们的递归存在问题,如果我们找一个不存在的数救会报错,这个错误是死递归造成的错误

Exception in thread "main" java.lang.StackOverflowError
	at 查找算法.BinarySearch.binarySearch(BinarySearch.java:27)

那我们就得来写出这个递归的结束出口

改进

//二分查找
//@author 王
public class BinarySearch {
    

	public static void main(String[] args) {
    
		// TODO Auto-generated method stub
		int arr[] = {
    1,8,10,89,1000,1234};//必须是有序数组
		int resultIndex = binarySearch(arr, 0, arr.length -1, 123);
		if(resultIndex != -1){
    
			System.out.println(resultIndex);
		}else{
    
			System.out.println("没有找到这个数字");
		}
	}
	/**
	 * 
	 * @param arr			数组
	 * @param left			左边索引
	 * @param right			右边索引
	 * @param findValue		需要找的数字,找到返回下标,未找到返回-1
	 * @return
	 */
	//二分查找算法
	public static int binarySearch(int[] arr,int left,int right,int findValue) {
    
		if(left > right){
    
			return -1;
		}
		int mid = (left+right)/2;
		int midValue = arr[mid];
		if(findValue >midValue){
    
			//向右递归
			return binarySearch(arr, mid+1, right, findValue);
		}else if(findValue < midValue){
    
			//向左递归
			return binarySearch(arr, left, mid-1, findValue);
		}else{
    
			return mid;
		}
	}

}

我们再来扩充一点,也是老师的课后习题
{1,8,10,89,1000,1000,1000,1234} 当一个有序数组中,有多个相同的数值时,如何将所有的数值都查找到,比如这里的1000.

思路跟我上一个学的差不多,我们可以采用一个集合来存储我们的索引值,返回我们的集合

代码

public class BinarySearch {
    

	public static void main(String[] args) {
    
		// TODO Auto-generated method stub
		int arr[] = {
    1,8,10,89,1000,1000,1000,1234};//必须是有序数组
		ArrayList<Integer> resultIndex = binarySearch2(arr, 0, arr.length -1, 1000);
		if(resultIndex.size() == 0){
    
			System.out.println("没有找到这个数字");
		}else{
    
			System.out.println(resultIndex);
		}
	}
    public static ArrayList<Integer> binarySearch2(int[] arr,int left,int right,int findValue) {
    
			if(left > right){
    
				return new ArrayList<Integer>();
			}
			int mid = (left+right)/2;
			int midValue = arr[mid];
			if(findValue >midValue){
    
				//向右递归
				return binarySearch2(arr, mid+1, right, findValue);
			}else if(findValue < midValue){
    
				//向左递归
				return binarySearch2(arr, left, mid-1, findValue);
			}else{
    
				ArrayList<Integer> list = new ArrayList<Integer>();
				int temp = mid -1;
				//向左边扫描
				while(true){
    
					if(temp < 0 || arr[temp] != findValue){
    
						//退出
						break;
					}else{
    
						//否则就将temp放到集合中
						list.add(temp);
						temp -= 1;//temp左移
					}
				}
				list.add(mid);
				//向右扫描
				temp = mid +1;
				while(true){
    
					if(temp > arr.length - 1 || arr[temp] != findValue){
    
						//退出
						break;
					}else{
    
						//否则就将temp放到集合中
						list.add(temp);
						temp += 1;//temp左移
					}
				}
				return list;
			}
		}
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_22155255/article/details/112847063

智能推荐

python读取oracle数据_Python读写oracle数据库-程序员宅基地

文章浏览阅读971次。最近项目中需要用到Python调用oracle实现读写操作,踩过很多坑,历尽艰辛终于实现了。性能怎样先不说,有方法后面再调优嘛。现在把代码和注意点记录一下。1. 所需Python工具库cx_Oracle,pandas,可以使用通过控制台使用pip进行安装(电脑中已经安装)2. 实现查询操作#工具库导入import pandas as pdimport cx_Oracle#注:设置环境编码方式,可解..._pandas 分批读取oracle 表

基于JSP后台的志愿者小程序 毕业设计毕设作品欣赏_jsp参赛作品-程序员宅基地

文章浏览阅读767次。基于JSP后台的志愿者小程序_jsp参赛作品

固定资产管理系统日常业务有哪些-程序员宅基地

文章浏览阅读364次,点赞4次,收藏5次。它可以帮助企业完成固定资产的全生命周期管理,提升资产管理效率,降低成本。它涉及公司的长期投资、资产保值和资产报表的准确性。资产处理:当资产达到预定使用期或无法继续使用时,系统需要记录资产处理信息,包括处理日期、处理方法和价格。资产维护:系统需要提醒公司定期维护资产,以确保资产的正常使用。同时,系统还应记录维护的详细信息,包括维护日期、维护内容和维护费用。资产应用:系统需要记录使用单位、使用人员、使用次数等每个资产的使用情况。该系统可实现固定资产的高效管理,提升资产管理效率,降低成本。

android源码--activity启动源码分析_源码 判断启动的activity是否是 instant app-程序员宅基地

文章浏览阅读518次。1.app应用的真正入口是ActivityThread类中的main()方法。 2.调用Looper.prepareMainLooper()方法。 3.调用prepare(false)方法,这里的threadLocal其实就是一个map集合。这样新创建了一个Looper对象,添加到集合中。 在Looper的构造器中,初始化了消息队列并且获取当前的线程 4.调用myLoope..._源码 判断启动的activity是否是 instant app

如何获取Gradle dependencies report(gradle依赖报告)_gradle license dependency report-程序员宅基地

文章浏览阅读1.2k次。这部分内容是之前那个依赖测试包问题看到的答案下面的,有一位大佬梳理了一下这个过程,我在这边翻译一下也供大家参考吧:步骤1在项目根目录下执行获取依赖报告的gradle,比如gradle -q app:dependencies 详细的可以看这里这可以提供与该问题有关的以ASCⅡ码呈现的树,它会帮助你判断哪些是有冲突的版本+--- com.android.support.t..._gradle license dependency report

会动的底部导航栏-Lottie的应用-程序员宅基地

文章浏览阅读415次,点赞5次,收藏4次。随着Android的发展,用户审美的不断提高,你的app不仅得足够好用,UI也得让人感觉赏心悦目,今天无意间打开CSDN看帖子时,发现点击底部导航栏时,图标是会播放动画的,一时好奇是如何实现的,然后就浅浅的研究了下~

随便推点

你最大的优点是什么?(回答技巧及范例)-程序员宅基地

文章浏览阅读829次。http://bbs.yingjiesheng.com/thread-186906-1-1.html你最大的优点是什么?问题分析: 在这个问题上, 面试官关注的问题有两点。第一, 申请人没有撒谎, 而是真实地阐述了自己的优点。第二, 他所阐述的优点, 恰好是这个职位所需要的素质。有很多时候, 对于一个岗位而言的优点, 会成为另一个岗位的缺点。比如说, 如果你具备很强的领导能力, 往往不适合..._说说你们最大的优点是什么

软件工程文档编写标准包括哪些内容_工程文档写作都有什么-程序员宅基地

文章浏览阅读1.2k次。在项目开发过程中,应该按要求编写好十三种文档,文档编制要求具有针对性、精确性、清晰性、完整性、灵活性、可追溯性。   ◇ 可行性分析报告:说明该软件开发项目的实现在技术上、经济上和社会因素上的可行性,评述为了合理地达到开发目标可供选择的各种可能实施方案,说明并论证所选定实施方案的理由。   ◇ 项目开发计划:为软件项目实施方案制订出具体计划,应该包括各部分工作的负责人员、开发的进度、开发经费的_工程文档写作都有什么

互联网产品中的平台、社区、软件、网站、品牌等科普_小米社区和oppo社区 谁算是交易型社区-程序员宅基地

文章浏览阅读2k次。科普大杂烩_小米社区和oppo社区 谁算是交易型社区

STL模型分割工具:解放3D打印的尺寸限制_分解stl模型-程序员宅基地

文章浏览阅读334次,点赞6次,收藏5次。STL模型分割工具是一个简单易用的在线应用,无需安装任何软件,只需通过网页浏览器即可操作。_分解stl模型

LeetCode刷题总结(九)29 - 31 -- 二进制倍增,位运算,滑动窗口_leetcode 倍增-程序员宅基地

文章浏览阅读217次。(一)LeetCode29:两数相除暴力做法是循环 x -= y,x为被除数,y为除数,减到 x 小于 y 为止,每减一次计数变量 ++,最后输出计数变量。然而以上这种做法显然是会超时的!!!高级解法是二进制移位倍增,其实这也是计算机实现乘除法的本质。..._leetcode 倍增

三缸活塞泵 三角机器人 路由器盖板模具设计 打印机 烘箱滚筒控制板 变频器盒模具设计 机械臂末端执行器 上料机 无人机 摩托车 装配自动线 电机三维图-程序员宅基地

文章浏览阅读93次。3D digital model drawing of three-degree-of-freedom planetary gearbox Solidworks design with STEP/三自由度行星变速箱3D数模图纸 Solidworks设计 附STEP。STP format of 3D drawing of simple model of three-wheeled motorcycle/摆摊三轮摩托车简易模型3D图纸STP格式。

推荐文章

热门文章

相关标签