二分查找算法

这篇博客介绍了二分查找的基本原理和递归实现,强调了在有序数组中查找特定数值的过程。在遇到重复数值时,提出了一种改进方法,不仅找到目标值,还能获取所有相同数值的下标。通过向左右两侧扩展,将所有匹配的元素添加到结果集合中。这种方法提高了查找效率,适用于包含多个相同数值的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分查找

对一个有序数组查找,涉及递归的方法

二分查找思路

1、首先先确定该数组中间的下标mid=(left+right)/2
2、然后让需要查找的数findVaue和arr[mid]比较
2、1findValue>arr[mid],说明要查找的数在mid的右边,因此需要递归的向右查找。
2、2findValue<arr[mid],说明要查找的数在mid的左边,因从需要递归向左查找。
2、3findValue == arr[mid]说明找到,就返回

什么时候结束递归?
1、找到就结束递归
2、递归完整个数组,仍然没有找到findValur,也需要结束递归,当left>right就需要退出
在这里插入图片描述

代码实现

package com.search;

/**
 * 使用二分查找的前提是:该数组是有序的
 * 此时使用数组是从小到大
 * */
public class BinarySearch {
    public static void main(String[] args) {
        int[] arr={1,8,10,89,100,1234};
        int resIndex = binarySearch(arr,0,arr.length-1,134);
        System.out.println(resIndex);
    }

    //二分查找算法

    /**
     *
     * @param arr 数组
     * @param left  左边索引
     * @param right   右边索引
     * @param findValue  查找的值
     * @return  如果找到就返回下标,如果没有找到就返回-1
     */
    public static int binarySearch(int[] arr,int left,int right,int findValue){

        //当left>right时,说明递归了整个数组,但是没有找到
        if (left>right){
            return -1;
        }
        int mid = (left+right)/2;
        int midVal = arr[mid];
        if (findValue > midVal){//向右递归
            return binarySearch(arr,mid+1,right,findValue);
        }else if (findValue<midVal){//向左递归
            return binarySearch(arr,left,mid-1,findValue);
        } else {
            return mid;
        }
    }
}

课后思考题

{1,8,10,89,100,100,1234};当一个有序数组中,有多个相同的数值时,如何将所有的数值都查找到,比如这里的100?

package com.search;

import java.util.ArrayList;
import java.util.List;

/**
 * 查找数组中某个元素的下标(所有下标)
 */
public class BinarySearch2 {
    public static void main(String[] args) {
        int[] arr={1,8,10,89,100,100,1234};
        List<Integer> resIndexList = binarySearch(arr, 0, arr.length - 1, 100);
        System.out.println(resIndexList);
    }

    /*
    思路分析:
    1、在找到Mid的值时,不要立即返回
    2、向mid索引值左边扫描,将所有满足100的元素加入到ArrayList中
    3、向mid索引值右边扫描,将所有满足100的元素的小标,加入到集合ArrayList中
    4、将ArrayList返回就可以了
     */
    public static List<Integer> binarySearch(int[] arr, int left, int right, int findValue){

        //当left>right时,说明递归了整个数组,但是没有找到
        if (left>right){
            return new ArrayList<Integer>();
        }
        int mid = (left+right)/2;
        int midVal = arr[mid];
        if (findValue > midVal){//向右递归
            return binarySearch(arr,mid+1,right,findValue);
        }else if (findValue<midVal){//向左递归
            return binarySearch(arr,left,mid-1,findValue);
        } else {
            List<Integer> resIndexList = new ArrayList<>();
            //向mid索引值左边扫描,将所有满足100的元素加入到ArrayList中
            int temp = mid-1;
            while (true){
                if (temp<0 || arr[temp]!=findValue){//退出
                    break;
                }
                //否则,就把temp放入到resIndexList
                resIndexList.add(temp);
                temp -= 1;//temp左移
            }
            resIndexList.add(mid);

            //向mid索引值右边扫描,将所有满足100的元素的小标,加入到集合ArrayList中
            temp = mid +1;
            while (true){
                if (temp>arr.length-1 || arr[temp]!=findValue){//退出
                    break;
                }
                //否则,就把temp放入到resIndexList
                resIndexList.add(temp);
                temp += 1;//temp左移
            }
            return resIndexList;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值