Detailed Explanation: Binary Search Algorithm [Java Implementation] (Recursive && Non-recursive)

Table of contents

1. Basic concepts

2. Graphical thinking analysis of binary search algorithm [recursive method]:

Code:

Binary search optimization: realize all indexes returning multiple identical numbers in the array

3. Graphical thinking analysis of binary search algorithm [non-recursive method]:


1. Basic concepts

Binary Search (Binary Search) algorithm, also known as binary search algorithm. Binary search is aimed at an ordered data set, and the search idea is somewhat similar to the divide and conquer idea. Each time, by comparing with the middle element of the interval, the interval with search is reduced to half of the previous one, until the element to be searched is found, or the interval is reduced to 0.

2. Graphical thinking analysis of binary search algorithm [recursive method]:

Example: Please perform a binary search on an ordered array {1, 8, 10, 89, 1000, 234}, enter a number to see if the number exists in the array, and find the subscript, if not, it will prompt "No such number ".

Define variables :

        mid: the middle subscript of the array to be binary searched;

        left: the leftmost subscript of the array to be binary searched

        right: the rightmost subscript of the array to be binary searched

        findVal: the number we want to binary search

1, first determine the subscript mid= (left+right)/2 in the middle of the array

2 , and then compare the number findVal to be found with arr[mid] :

        2.1 findVal>arr[mid] , indicating that the number to be searched is on the right side of mid, so recursive search to the right is required

        2.2 findVal <arr[mid] , indicating that the number you want to find is on the left of mid, so you need to search left recursively.

        2.3 findval==arr[mid] indicates that if it is found, it will return .

3 , Conditions for ending recursion:
        1) End recursion when found.
        2) Recursively complete the entire array, if findval is still not found, you need to end the recursion.

        3) When left > right, you need to exit the recursion.

4. Disadvantages:

        When there are multiple identical values ​​in an ordered array, only the index of the position of one value will be returned.

Code:

//注意二分查找的前提是:该数组是有序的
public class BinarySearch {//二分查找

    public static void main(String[] args) {
        //测试二分查找:
        int[] arr = {1,8,10,89,1000,1234};
        int val = binarySearch2(arr, 0, arr.length - 1, 36);
        System.out.println(val);
    }

    /*二分查找【不能查找重复的值的索引,相同的值只会返回一个值的索引】
    arr 数组
    left 数组最左边的索引
    right 数组最右边的索引
    findVal 要查找的值
    如果找到就返回下标,如果没有找到就返回-1
    * */
    public static int binarySearch(int[] arr, int left, int right, int findVal) {
    // findVal < arr[0] || findVal > arr[arr.length - 1]说明要查找的findVal值再数组中不存在
    //当left>right时说明,已经递归了整个数组,但是没有findVal值
        if (left > right || findVal < arr[0] || findVal > arr[arr.length - 1]) {//当满足其中任意一个条件时,就要退出递归。
            return -1;
        }
        int mid = (left + right) / 2;//mid表示数组中间的下标
        int midVal = arr[mid];//midVal表示数组中间的值
        if (findVal > midVal) {
            //向右递归
            return binarySearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) {
            //向左递归
            return binarySearch(arr, left, mid - 1, findVal);
        } else {//表示:findVal==midVal找到要查找的值
            return mid;
        }
    }
}

Binary search optimization: realize all indexes returning multiple identical numbers in the array

//注意二分查找的前提是:该数组是有序的
public class BinarySearch {//二分查找

    public static void main(String[] args) {
    //测试:当有数组里多个相同的数值时,将所有的数值都查找到返回下标索引。比如这里的1000
        int[] arr = {1,8, 10, 89, 1000, 1000, 1 ,34};
        List val = binarySearch2(arr, 0, arr.length - 1, 1000);
        System.out.println(val);
    }


/*二分查找优化【查找出多个相同的的值的下标索引】
 arr 数组
 left 数组最左边的索引
 right 数组最右边的索引
 findVal 要查找的值
 如果找到就返回下标,如果没有找到就返回-1
* */
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
    if (left > right || findVal < arr[0] || findVal > arr[arr.length - 1]) {
        return new ArrayList<Integer>();
    }
    int mid = (left + right) / 2;//mid表示数组中间的下标
    int midVal = arr[mid];//midVal表示数组中间的值
    if (findVal > midVal) {
        //向右递归
        return binarySearch2(arr, mid + 1, right, findVal);
    } else if (findVal < midVal) {
        //向左递归
        return binarySearch2(arr, left, mid - 1, findVal);
    } else {//表示:findVal==midVal【经过前面的递归,最终都会有findVal==midVal】
        /*
         * 思路分析:
         * 1,在找到mid索引值,不马上返回
         * 2,向mid索引值的左边扫描,将所有满足findVal的值的下标加入到ArrayList集合里
         * 3,向mid索引值的右边扫描,将所有满足findVal的值的下标加入到ArrayList集合里
         * 4,将ArrayList集合返回
         * */
        ArrayList<Integer> integers = new ArrayList<>();
        //向mid索引值的左边扫描,将所有满足findVal的值的下标加入到ArrayList集合里
        int temp = mid - 1;//temp表示向左扫描的索引
        while (true) {
            if (temp < 0 || arr[temp] != findVal) {//退出
                break;
            }
            //否则,就把temp放入集合integers中
            integers.add(temp);
            temp -= 1;
        }
        integers.add(mid);//刚好mid就是要找的findVal值
        //向mid索引值的右边扫描,将所有满足findVal的值的下标加入到ArrayList集合里
        temp = mid + 1;//temp表示向右扫描的索引
        while (true) {
            if (temp > arr.length - 1 || arr[temp] != findVal) {//退出
                break;
            }
            //否则,就把temp放入集合integers中
            integers.add(temp);
            temp += 1;
        }
        return integers;
    }
}

3. Graphical thinking analysis of binary search algorithm [non-recursive method]:

The non-recursive method is much simpler than the recursive method, and it can be realized only by the nested use of while loops and if-else.

public class BinaryDearchNoRecur {//二分查找的非递归实现

    public static void main(String[] args) {
        //测试
        int[] arr = {1, 3, 8, 10, 11, 67, 100};
        int index = binaryDearch(arr, 13);
        System.out.println("index=" + index);
    }

    /**
     * 二分查找的非递归实现
     * @param arr    待查找的数组,arr是升序排列
     * @param target 需要查找的数
     * @return 返回对应数组下标,没有返回-1
     */
    public static int binaryDearch(int[] arr, int target) {
        int left = 0;//left表示数组最左边的索引
        int right = arr.length - 1;//表示数组最右边的索引
        while (left <= right) {//说明可以继续查找
            int mid = (left + right) / 2;//mid表示数组中间的索引
            if (arr[mid] == target) {
                return mid;
            } else if (arr[mid] > target) {
                right = mid - 1;//需要向左边查找
            } else {
                left = mid + 1;//需要向右边查找
            }
        }
        return -1;
    }
}

There will be times when the wind and the waves cleave, hang the clouds and sail straight to the sea!

Guess you like

Origin blog.csdn.net/m0_52729352/article/details/121930170