二分查找详解


概述

二分查找又称折半查找,是一种效率较高的查找方法。


使用条件

1.必须满足顺序储存结构
2.必须满足元素有序排列
3.必须满足储存结构中元素互异


原理

由于数组元素的有序性和互异性,通过下标得到数组内元素间相对的大小关系,定义三个变量:两个边界变量确定查找范围,一个取值两个边界变量中间值的中间变量用于同被查找值比较大小、从而改变边界变量的值进而缩小查找区间的范围、重新确定中间值,并重复这一过程直到中间值下标等于查找值、最小值下标大于最大值下标,退出循环。


二分查找的流程(正序)

1.使用整型数据数组储存正序排列互异元素

        int[] arr1 = {1,2,3,4,5,6,7,8,9};

2.获取查找数据

        //使用Scanner获取输入的数据
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();

3.定义最大值下标、最小值下标、中间值下标

        //最大值下标
        int maxIndex = arr1.length - 1;

        //最小值下标
        int minIndex = 0;

        //中间值下标
        int midIndex = (maxIndex + minIndex) / 2;

4.因为不确定循环次数所以使用while循环

        while(true){
          //正序排列下,查找数据大于中间值数据
          if(arr1[midIndex] < num){
            //最小值下标 = 中间值下标 + 1
            minIndex = midIndex + 1;
          }
          //正序排列下,查找数据小于中间值数据
          else if(arr1[midIndex] > num){
            //最大值下标 = 中间值下标 - 1;
            maxIndex = midIndex - 1;
          }
          else{
            break;
          }

          //正序条件下,最小值下标大于最大值下标时
          if(minIndex > maxIndex){
            midIndex = -1;
            break;
          }

          //更新中间下标变量
          midIndex = (minIndex + maxIndex) / 2;
        }

        System.out.println(midIndex > 0 ? "找到元素下标为"+midIndex : "找不到该元素!");

初始状态下的三个坐标变量值固定的,不会随着查找数据的改变而改变。如图所示:

执行while循环中的方法体时,我们需要特别注意中间下标值和查找值大小的关系、即不同大小关系对应的执行体,例如:

查找数据为6时,查找值大于中间下标值,最小值下标变量 = 中间值下标变量 + 1,此时三变量下标值关系:

最小下标变量大于最大下标变量关系不成立,最大下标变量加最小下标变量的和除2的商赋值给中间变量,此时三变量下标值关系:

查找值小于中间下标值,最大值下标变量 = 中间值下标变量 - 1,此时三变量下标值关系:

最小值下标变量大于最大值下标变量关系依然不成立,最大下标变量加最小下标变量的和除2的商赋值给中间变量,此时三变量下标值关系:

中间下标值既不大于、也不小于查找值,退出循环。


二分查找的流程(倒序)

流程和正序相同,我们只说不一样的部分:

1.源数据倒序

        int[] arr2 = {9,8,7,6,5,4,3,2,1};

2.倒序情况下,最大值下标变量、最小值下标变量与正序的赋值相反,中间值的赋值运算不变。


        //最小值下标
        int minIndex = arr2.length - 1;

        //中间值下标
        int midIndex = (maxIndex + minIndex) / 2;

倒序情况下,初始三下标变量的关系如下:

3.倒序情况下,当最大值下标变量大于最小值下标变量时,查找数据不存在,这与正序条件相反。

        if(maxIndex > minIndex){
          midIndex = -1;
          break;
        }

4.倒序情况下,同样采用while循环,中间下标值和查找值的大小关系条件不变,但不同大小关系对应的方法体与正序的情况不同,举例说明:

查找数据为6时,查找值大于中间下标值,最小值下标变量 = 中间值下标变量 - 1,此时三变量下标值关系:

最大值下标变量大于最小值下标变量的关系不成立,最大值下标变量加最小值下标变量的和除2的商赋值中间下标变量。此时三变量下标值关系:

查找值大于中间下标值,最大值下标变量 = 中间值下标变量 + 1,此时三变量下标值关系:

最大值下标变量大于最小值下标变量的关系不成立,最大值下标变量加最小值下标变量的和除2的商赋值中间下标变量。此时三变量下标值关系:

查找值仍小于中间下标值,最大值下标变量 = 中间值下标变量 + 1

最大值下标变量大于最小值下标变量的关系不成立,最大值下标变量加最小值下标变量的和除2的商赋值中间下标变量。此时三变量下标值关系:

中间下标值既不大于、不小于查找值时,退出循环。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM