高频面试题之:二分查找(含递归与非递归)

如果笔试题里只提供了非递归的参数,但是想用递归的方法写怎么办?
----方法重载!!

1、递归写法:

/**
 * 二分查找思路:
 *      整体思路:三个指针,一个头一个尾一个中间。比较目标元素的值是否大于中间,如果大,就在后半段继续进行操作,如果小,就在前半段操作
 *      具体写法:
 *          1、确定中间下标:mid = (left + right)/2
 *          2、让查找目标数target和arr[mid]比较
 *              2.1 target > arr[mid] 查找的数在mid右边,应该向右递归查找
 *              2.2 target < arr[mid] 查找的数在mid右边,应该向右递归查找
 *              2.3 target = arr[mid] return
 *
 *       如何做到向左边、右边的数组查?---- private static int binarySearch(int[] arrs, int left, int right, int target)
 *          这个方法里面能够指定left和right,如果向左,只要在递归的时候让right=mid-1即可
 *
 */

代码如下:

public class BinarySearch {

    public static void main(String[] args) {
        //二分法一定要注意是已经排序好的数组!!!!
        int[] arrs = {1,2,3,4,5,6,7,8,9};

        //肯定使用到递归,用到递归,那就要有left、right并且注意最好习惯是左闭右闭
        int first = 0;
        int last = arrs.length - 1;//右闭
        int target = 2;
        //int result = binarySearch(arrs,first,last,target);
        draft(arrs,first,last,target);

        /*for (int data :
                arrs) {
            System.out.print(data + " ");
        }

        if (result != -1){
            System.out.println("找到目标值:" + target + "; 其下标位置为:" + result);
        }else {
            System.out.println("没有找到目标");
        }*/
    }

    private static int binarySearch(int[] arrs, int left, int right, int target) {

        int result = -1;
        //如果输入了一个数组没有的元素会怎么样?------>栈内存溢出
        //如何解决?----->最后一次执行的时候      left = right ,再执行下去,left就会 > right
        if (left > right){
            result = -1;
            return result;
        }

        int mid = (right + left) / 2;
        if (target == arrs[mid]){
            //多次递归后,最后只要在里面的值,可能能被找到且为该次递归的mid
            //System.out.println("找到目标值:" + target + "; 其下标位置为:" + mid);
            result = mid;
            return result;
        }else if (target < arrs[mid]){
            //在左半边的数组中
            return binarySearch(arrs,left,mid-1,target);
        } else if (target > arrs[mid]) {
            //在右半边数组
            return binarySearch(arrs,mid + 1, right, target);
        }
        return result;
    }
	
	//写的草稿
    public static void draft(int[] arrs, int left, int right, int target) {

        if (left > right){
            System.out.println("未找到目标元素");
            return;
        }

        int mid = (left + right) / 2;
        if (target == arrs[mid]){
            System.out.println("成功查找到目标值,下标为: "+mid+" 值为: " + arrs[mid]);
            return; //之所以用不上,是因为后面都是else if 语句,这个条件满足了,其他肯定不满足!那也就退出当前栈了,回到上一次递归的地方
        }else if (target > arrs[mid]){
            //后半段
            draft(arrs,mid + 1,right, target); //这里的right是一直在变化的,因为在递归的过程中。
        }else if (target < arrs[mid]){
            //前半段
            draft(arrs,left,mid-1,target);
        }else {

            return;
        }
    }
}

2、非递归

/**
 * 非递归的二分查找:
 *      特点是不需要在查找的方法中写left,right 指针了
 *      因为递归的时候,就是在满足某个条件后,去调用查找方法,同时修改left = mid -1或right = mid +1因此方法里肯定是要这两个形参的
 *
 *      现在使用循环的方法完成二分查找,形参就可以不要left、right指针,而可以直接在内部写
 *          由于使用循环,满足某个条件,让left = mid -1 或right = mid +1 ,进入下一次循环再找,找到了就退出
 */

代码实现:

 public class BinarySearchNonRecursive {
    public static void main(String[] args) {
        int arrs[] = {0,1,2,3,4,5,6,7,8,9};
        int res = binarySearch(arrs, 80);
        if (res == -1){
            System.out.println("未找到目标元素");
        }else {
            System.out.println("找到目标元素: " + res);
        }

    }

    public static int binarySearch(int[] arrs,int target){
        int left = 0; //初始化
        int right = arrs.length -1;

        while (left <= right){
            int mid = (left + right) / 2 ;
            if (target == arrs[mid]){
                return arrs[mid];
            }else if (target > arrs[mid]){
                left = mid + 1;
            } else if (target < arrs[mid]) {
                right = mid -1 ;
            }
        }
        //while循环都结束了还没找到,说明已经不满足left < right ,找不到元素
        return  -1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前Facebook工程师 打造王者级课程                            覃超 Facebook 早期员工&多年面试官、曾作为 Facebook Messenger Tech Lead,主导和参与了 Facebook App、Facebook Messenger、Facebook Phone 等产品的研发工作。 现在,覃超老师致力于计算机科学领域的培训指导,经他指导的学生,90%以上拿到了硅谷公司或国内顶级互联网公司的offer。 推动0到3岁程序员 打通职业发展路径 数据结构与算法计算机学科知识结构的核心和技术体系的基石,随着科技的飞速发展,数据结构的基础性地位反而更加坚固,是每一个程序员必须掌握的底层核心技能! 多岗位必备技能 快速提升编程内功   作为一名程序员,无论是任何岗位,掌握数据结构与算法,就可以在面试前建立自己的算法技术体系,同时有助于更好地阅读源码和设计编写一些复杂的工具,快速提升编程内功! 建立框架性知识体系 覆盖重要知识点 很多人认为可能除了面试,之后再也用不到据结构与算法了,但是如果程序员想拔高一个层次,数据结构与算法是很重要的一部分,《全解数据结构与算法》帮你完成角色的转变! 透彻讲解底层核心原理 拓展能力上限 很多人认为可能除了面试,之后再也用不到据结构与算法了,但是如果程序员想拔高一个层次,数据结构与算法是很重要的一部分,《全解数据结构与算法》帮你完成角色的转变!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值