作者前言

大家好,我是阿濠,今篇内容跟大家分享的是查找算法之二分查找法,很高兴分享到segmentfault与大家一起学习交流,初次见面请大家多多关照,一起学习进步.

一、二分查找法的介绍

是一种在有序数组中查找某一特定元素的搜索算法。

1.搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索结束

2.如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且重新开始从中间元素进行比较。

3.如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半

二、通过应用示例认识线性查找算法

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

步骤思路
1.确定数组中间数的下标mid=(left+right)/2
2.将查询的数findValue和中间数arr[mid]进行比较
3.若findVale>arr[mid],则说明查找的数findValue在右边,进行递归向右查询
4.若findVale<arr[mid],则说明查找的数findValue在左边,进行递归向左查询
5.若findVale = =arr[mid],则说明查找的数已找到并返回下标

结束递归思路
1.找到findValue结束递归
2.数组递归完仍未找到findValue也结束递归,当left>right结束递归退出

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

    //一、没有找到的情况
    if(left > right){
        return -1;
    }

    //二、找到的情况
    //中间下标
    int mid = (left + right) / 2;
    int midVal =arr[mid];//中间下标对应的值

    if(findVal>midVal) {
        //若`findVale>arr[mid]`,则说明查找的数`findValue在右边`,进行递归`向右查询`
        return binarySearch(arr, mid + 1, right, findVal);
    }else if (findVal<midVal){
        //若`findVale<arr[mid]`,则说明查找的数`findValue在左边`,进行递归`向左查询`
        return binarySearch(arr,left,mid-1,findVal);
    }else{
        //若`findVale = =arr[mid]`,则说明`查找的数已找到并返回下标`
        return mid;
    }
}
public static void main(String[ ] args) {
    int arr[]={ 1, 8, 10, 89, 1000, 1234};
    int rearchIndex = binarySearch(arr,0,arr.length-1,8);
    if(rearchIndex == -1) {
        System. out. println("没有找到");
    } else {
        System .out. println("找到,下标为=" + rearchIndex);
    }
}
运行结果如下:
找到,下标为 = 1

三、数组中出现重复数值

有序数组:{1,8, 10, 89, 1000, 1000, 1234},有多个相同的数值时,如何将所有的数值都查找到,比如这里的1000.

//二分查找算法
/**
 * 课后思考题: {1,8, 10,89,1000, 1000, 1234} 当一个有序数组中,
 * 有多个相同的数值时,如何将所有的数值都查找到,比如这里的1000
 *
 * 思路分析
 * 1.在找到mid 索引值,不要马上返回.
 * 2.向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
 * 3.向mid 索引值的右边扫描,将所有满足1000, 的元素的下标,加入到集合ArrayList
 * 4.将Arraylist返 回
 */
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {

    //一、没有找到的情况
    if(left > right){
        return new ArrayList<Integer>();
    }

    //二、找到的情况
    //中间下标
    int mid = (left + right) / 2;
    int midVal =arr[mid];//中间下标对应的值

    if(findVal>midVal) {
        //若`findVale>arr[mid]`,则说明查找的数`findValue在右边`,进行递归`向右查询`
        return binarySearch2(arr, mid + 1, right, findVal);
    }else if (findVal<midVal){
        //若`findVale<arr[mid]`,则说明查找的数`findValue在左边`,进行递归`向左查询`
        return binarySearch2(arr,left,mid-1,findVal);
    }else{
        /**思路分析
         * 1.在找到mid 索引值,不要马上返回.
         * 2.向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
         * 3.向mid 索引值的右边扫描,将所有满足1000, 的元素的下标,加入到集合ArrayList
         * 4.将Arraylist返回
         * */
        ArrayList<Integer> rearchIndexlist=new ArrayList<Integer>();
        //向mid 索引值的左边扫描,将所有满足1000,的元素的下标,加入到集合ArrayList
        int temp= mid - 1;
        while(true){
            //证明向mid 索引值的左边扫描 没有找到相同的findValue值
            if(temp < 0 || arr[temp] != findVal ){
                break;
            }
            //证明有相同的findValue值,放入rearchIndexlist里
            rearchIndexlist.add(temp);
            temp -= 1;//向左移
        }
        //将找到的mid 索引值 放入rearchIndexlist 中
        rearchIndexlist.add(mid);

        //向mid 索引值的右边扫描,将所有满足1000, 的元素的下标,加入到集合ArrayList
        temp= mid + 1;
        while(true){
            //证明向mid 索引值的右边扫描 没有找到相同的findValue值
            if(temp > arr.length -1 || arr[temp]!= findVal ){
                break;
            }
            //证明有相同的findValue值,放入rearchIndexlist里
            rearchIndexlist.add(temp);
            temp += 1;//向右移
        }
        return rearchIndexlist;
    }
}
public static void main(String[ ] args) {

    int arr[]={ 1, 10, 89, 1000, 1000, 1234};

    List integerList= binarySearch2(arr,0,arr.length-1,1000);
    System.out.println("找到的所有值:"+ integerList);
        
}

运行结果如下:
找到的所有值:[3,4]

28640
116 声望25 粉丝

心有多大,舞台就有多大