你好!二分查找【JAVA】

1.初次相识

二分查找又称折半查找,是一种在有序数组中查找特定元素的算法。二分查找的基本思想是:通过不断地二分数组的中间元素,缩小查找区间,直到找到目标元素或者确定目标元素不存在为止。

二分查找的时间复杂度为O(logn),比线性查找的时间复杂度O(n)要小很多,但是二分查找的前提是必须在有序数组中进行。

2.思想分析 

  • 1.确定该数组的中间下标 middle=(left+right)/2
  • 2.需要查找的数index和array【middle】比较
  • 2.1 index > array【middle】,说明要查找的数在middle的右边,递归向右查找
  • 2.2 index < array【middle】,说明要查找的数在 middle的左边,递归向左查找
  • 2.3 index == array【middle】,说明找到,返回
  • 什么时候递归结束??
  • 1.找到就结束
  • 2.递归完整个数组,未找到,也许结束,条件: lift > rigtht

3.代码实现 

  public static int binarySearch(int[] arr, int left, int right, int index) {
        //直接结束递归
        if (left > right) {
            return -1;
        }
        int middle = (left + right) / 2;
        int middleVal = arr[middle];
        if (index > middleVal) {
            return binarySearch(arr, middle + 1, right, index);
        } else if (index < middleVal) {
            return binarySearch(arr, left, middle - 1, index);
        } else {
            return middle;
        }
    }

发现一个问题,如果有重复数字,也只能返回第一数字的下标

你好!二分查找【JAVA】_第1张图片你好!二分查找【JAVA】_第2张图片

4.代码优化 

思路:

  • 1.再找到middle时,不要立马返回
  • 2.向middle索引的左边扫描,将满足条件元素的下标,加入到ArrayList集合
  • 3.向middle索引的右边扫描,将满足条件元素的下标,加入到ArrayList集合
  • 4.将ArrayList返回
  public static ArrayList binarySearch(int[] arr, int left, int right, int index) {
        //直接结束递归
        if (left > right) {
            return new ArrayList();
        }
        int middle = (left + right) / 2;
        int middleVal = arr[middle];
        if (index > middleVal) {
            return binarySearch(arr, middle + 1, right, index);
        } else if (index < middleVal) {
            return binarySearch(arr, left, middle - 1, index);
        } else {
            ArrayList list = new ArrayList<>();

            int temp = middle - 1;//向左边查找的第一个元素
            while (true) {
                if (temp < 0 || arr[temp] != middleVal) {//退出条件
                    break;
                }
                list.add(temp);//找到,放进集合
                temp--;//temp左移
            }
            list.add(middle);//中间的放进去
            temp = middle + 1;
            while (true) {
                if (temp > arr.length - 1 || arr[temp] != middleVal) {
                    break;
                }
                list.add(temp);
                temp++;
            }
            return list;
        }
    }

5.测试一把 

  public static void main(String[] args) {
        int[] array = new int[]{1, 2, 3, 4, 5, 6, 6};
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要查找的数字:");
        int num = scanner.nextInt();
        ArrayList lists = binarySearch(array, 0, array.length - 1, num);
        System.out.println("你查找的数字:" + num + ",下标:" + lists);
    }

你好!二分查找【JAVA】_第3张图片

你好!二分查找【JAVA】_第4张图片 你好!二分查找【JAVA】_第5张图片

你可能感兴趣的:(算法,java,idea)