zoukankan      html  css  js  c++  java
  • 二分查找算法

    二分查找前提

    进行二分查找的数组是有序数组

    二分查找算法思路

    • 首先确定该数组的中间下标 mid = (left+right)/2
    • 然后让需要查找的数和arr[mid]进行比较
      • findVal > arr[mid] 说明你要查找的数在mid的右边,因此需要递归向右进行查找
      • findVal < arr[mid] 说明你要查找的数在mid的左边,因此需要递归向左进行查找
      • findVal = arr[mid] 说明找到,返回

    注意:
    使用递归要特别注意结束条件,不然就会成为死递归

    • 找到就结束递归
    • 遍历完整个数组,仍然没有找到findVal,也需要结束递归 当left>right时就结束了

    代码实现

    实现返回找到的第一个值的下标

     public static void main(String[] args) {
            int[] arr = {1, 8, 10, 89, 1000, 1234};
            int index = binarySearch(arr, 0, arr.length - 1, 89);
            System.out.println("index = "+index);
        }
    
        /**
         * @param arr     数组
         * @param left    左边的下标
         * @param right   右边的下标
         * @param findVal 查找的值
         * @return 返回查找到的第一个下标
         */
        private static int binarySearch(int[] arr, int left, int right, int findVal) {
            if (findVal < arr[left] || findVal > arr[right] || left > right) { //没有找到
                return -1;
            }
            int mid = (left + right) / 2;
            if (findVal < arr[mid]) { //findVal小于中间值 ,则说明在左边,需要左递归
                return binarySearch(arr, left, mid - 1, findVal);
            } else if (findVal > arr[mid]) { // findVal大于中间值,需要向右递归
                return binarySearch(arr, mid + 1, right, findVal);
            } else { //相等
                return mid;
            }
        }
    

    返回多个下标

    如果数组中待查找的元素有多个,这时就需要返回多个下标.核心思想就是借助于上面查找到的一个下标,向左右两边依次查找,是否还有与findVal相等的值

    public class BinarySearch {
        public static void main(String[] args) {
            int[] arr = {1, 8, 10, 89,1000, 1000, 1000, 1000, 1000, 1234};
            List<Integer> indexList = binarySearch2(arr, 0, arr.length - 1, 1000);
            System.out.println("indexList = " + indexList);
        }
    
        /**
         * @param arr     数组
         * @param left    左边的下标
         * @param right   右边的下标
         * @param findVal 待查找的值
         * @return 返回查找元素下标的集合
         */
        private static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
            //递归结束条件
            if (findVal < arr[left] || findVal > arr[right] || left > right) {
                return new ArrayList<Integer>();
            }
            List<Integer> indexList = new ArrayList<>();
            int mid = (left + right) / 2;
            if (findVal < arr[mid]) {
                return binarySearch2(arr, left, mid - 1, findVal);
            } else if (findVal > arr[mid]) {
                return binarySearch2(arr, mid + 1, right, findVal);
            } else {
                //找到一个下标mid之后,需要像mid的左右两边进行遍历,把值相等的下标,添加到集合中返回
                int temp = mid - 1;
                //向左边查找
                while (true) {
                    if (temp < 0 || arr[temp] != findVal) {
                        break;
                    }
                    indexList.add(temp);
                    temp -= 1;
                }
    
                //添加mid
                indexList.add(mid);
    
                temp = mid + 1;
                //向右边查找
                while (true) {
                    if (temp > arr.length - 1 || arr[temp] != findVal) {
                        break;
                    }
                    indexList.add(temp);
                    temp += 1;
                }
    
                return indexList;
            }
        }
    
    
  • 相关阅读:
    浅谈 倍增/ST表
    Meetings S 题解
    排序模板
    Huffman 树
    2020.7.31 模拟赛 题解
    浅谈 最短路
    【lcez校内第三次考T1】【题解】folder
    【题解】 P2613 【模板】有理数取余
    【题解】P5535 【XR-3】小道消息
    【笔记】积性函数 与 欧拉函数
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/13835775.html
Copyright © 2011-2022 走看看