Java常见算法之二分法查找算法详解

一、简介

二分法查找,是在已经排好序的序列中,定义一个起始位置start(即序列第一个元素)和一个终止位置end(即序列最后一个元素),通过mid=(start+end)/2计算出中间位置,通过待查找元素与mid中间位置的元素进行比较,如果待查找元素比中间位置mid对应的值小,那么将end = mid -1(即将end结束位置移动到mid中间左边一个位置),如果比中间对应的值大,那么将start = mid + 1 (即将start的位置移动到mid右边一个位置),一直循环查找,直到start > end,证明没找到对应的元素,停止循环。

二、查找思路

【a】待查找有序数组序列:1, 2, 3, 4, 5, 6, 7  

起始: 定义start = 0 , end = 6, mid = (start + end ) / 2 = (0 + 6) / 2 = 3,arr[mid] = arr[3] = 4

【b】假设需要查找"2", 因为2 < arr[mid] = arr[3] = 4; 所以需要将end移动到mid左边一个位置,即end = mid - 1 = 3 - 1 = 2,

此时重新计算mid = (start +end ) / 2 =  (0 + 2) / 2 = 1; arr[mid] = arr[1] = 2 ,继续将2与arr[mid] = arr[1] = 2进行比较,发现相等,成功找到数字"2"所在的位置。

【c】假设需要查找"7",因为 7 > arr[mid] = arr[3] = 4,所以需要将start移动到mid右边一个位置,即start = mid + 1 = 4,此时重新计算mid = (start +end) / 2 = (4+ 6)/2 = 5, arr[mid] = arr[5] = 6, 因为7>arr[mid] = arr[5] = 6,所以还是需要将start移动到mid右边一个位置,即start = mid + 1 = 5 + 1 = 6,  此时重新计算mid =  (start +end) / 2 = (6 + 6) / 2 = 6.arr[6] = 7, 此时arr[mid] = arr[6] = 7,刚好等于待查找数字7,说明成功找到数字"7"所在的位置.

 【d】假设查找"0", 因为 0 <  arr[mid] = arr[3] = 4, 所以需要将end移动到mid左边一个位置,即end = mid - 1 = 3 - 1 = 2,此时重新计算mid = (start +end) / 2 = (0 + 2) / 2 = 1,arr[mid] = arr[1] = 2, 因为0 < arr[mid] = arr[1] = 2,所以需要将end移动到mid左边一个位置,即end = mid - 1 = 1 - 1 =  0, 此时mid = (start +end) / 2 = (0 + 0) / 2 = 0,arr[mid] = arr[0] = 1,因为0 < arr[mid] = arr[0] = 1,所以需要将end移动到mid左边一个位置,即end = mid - 1 = 0 - 1 = -1 ,因为此时start = 0, end = -1,start >end,即start 已经大于end结束位置,说明没有找到相应的元素0。

三、算法实现

public class BinarySearchUtils {

    /**
     * 根据指定值查找在数组中的位置
     *
     * @param arr   待查找有序数组
     * @param value 指定值
     * @return 返回值在数组中对应的下标位置
     */
    public static int binarySearch(int[] arr, int value) {
        //起始位置
        int start = 0;
        //结束位置
        int end = arr.length - 1;

        while (true) {
            //计算中间位置下标
            int mid = (start + end) / 2;
            //中间值
            int midValue = arr[mid];

            if (value == midValue) {
                return mid;
            } else {
                //待查找数值比中间值小,需要将end = mid - 1
                if (midValue > value) {
                    end = mid - 1;
                } else {
                    //待查找数值比中间值大,需要将start = mid + 1
                    start = mid + 1;
                }
            }

            if (start > end) {
                //start > end,说明未找到相应的元素,返回-1
                return -1;
            }
        }
    }

}

测试:

public class TestBinarySearchUtils {

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
        int index1 = BinarySearchUtils.binarySearch(arr, 2);
        System.out.println(index1);
        int index2 = BinarySearchUtils.binarySearch(arr, 7);
        System.out.println(index2);
        int index3 = BinarySearchUtils.binarySearch(arr, 0);
        System.out.println(index3);
    }

}

测试结果:

四、总结

本文是作者对二分查找算法的一些总结以及思路,仅供大家参考学习,一起学习一起进步。

猜你喜欢

转载自blog.csdn.net/Weixiaohuai/article/details/83188174