数据结构学习(十二):二分查找

一、思路

  1. 首先确定该数组的中间的下标;
  2. 然后让需要查找的数findVal和arr[mid]比较;
    2.1 findVal>arr[mid],说明要查找的数在mid的右边,因此需要递归地向右查找;
    2.2 findVal<arr[mid],说明要查找的数在mid的左边,因此需要递归地向左查找;
    2.3 findVal==arr[mid],找到,返回;
  3. 什么时候结束递归
    3.1 找到结束递归;
    3.2 递归完整个数组,仍然没有找到findVal,left>right时结束。

二、代码

//arr:数组
    //left:左边的索引
    //right:右边的索引
    //findVal:要找的值
    //如果找到就返回下标,没有找到就返回-1
    public static int binarySearch(int[] arr, int left, int right, int findVal) {
        //当left > right时,说明递归整个数组,但是没有找到
        if(left > right) {
            return -1;
        }

        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if(findVal > midVal) { //向右递归
            return binarySearch(arr, mid + 1, right, findVal);
        }else if(findVal < midVal) { //向左递归
            return binarySearch(arr, left, mid - 1, findVal);
        }else {
            return mid;
        }
    }

三、当查找多个相同的数字时

//如何找到一个有序数组中有多个相同的数值时,如何将所有的数组都查找到
    //如果有多个,按照上面的方法,将返回最右边那个的索引
    /*
        思路分析:
        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) {
        //当left > right时,说明递归整个数组,但是没有找到
        if(left > right) {
            return new ArrayList<Integer>();
        }

        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if(findVal > midVal) { //向右递归
            return binarySearch2(arr, mid + 1, right, findVal);
        }else if(findVal < midVal) { //向左递归
            return binarySearch2(arr, left, mid - 1, findVal);
        }else {
            ArrayList<Integer> resIndexList = new ArrayList<>();

            //向mid的左边扫描,将所有满足1000元素的下标,加入到ArrayList
            int temp = mid - 1;
            while (true) {
                //退出
                if(temp < 0 || arr[temp] != findVal) {
                    break;
                }

                //将temp放入到resIndexList
                resIndexList.add(temp);
                //temp左移
                temp -= 1;
            }
            resIndexList.add(mid);

            //向mid的右边扫描,将所有满足1000元素的下标,加入到ArrayList
            temp = mid + 1;
            while (true) {
                //退出
                if(temp > arr.length - 1 || arr[temp] != findVal) {
                    break;
                }

                //将temp放入到resIndexList
                resIndexList.add(temp);
                //temp右移
                temp += 1;
            }

            return resIndexList;
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章