数据结构 数组的二分法查找

  1. 前提,数组已经按照从大到小或者从小到大排好序了。(注: 以下算法原理按照数组从小到大排序好了的)
  2. 算法原理
    1. 第一次从数组的中间找(如果是奇数个元素的数组就找最中间的那个,如果是偶数个元素组成的数组就就找中间偏右的那个)
    2. 如果发现这个中间值比要找的值小,就截取数组的右半部分(如果是奇数个元素组成的数组,就截取包括最中间那个值和其右边的值组成的数组)。反之就截取左边的。
    3. 采用类似递归的方式,将新数组代替原来的数组再进行依次 步骤2, 直到数组最中间的那个数和要找的数一致为止。
  3. 代码讲解
    1. 第一个要明白的就是奇数个元素数组用它的length属性除以2的到的是一个小数,java会自动向下取整,整个代码就是基于这个写的,因为向下取整了,所以得出来的这个数的下标正正好是数组排在正中间的那个数。(例如length为9, 9 / 2 = 4, 下标为4的就是第五个元素了,前边有0,1,2,3,后边有5,  6,7,8)
    2. 如果是偶数个元素组成的数组,length除以2得到的是中间偏右的那个数,这个也是根据向下取整得到的。(例如length为10, 10 / 2 = 5, 下标为的就是第六个元素了,前边有0,1,2,3,4  后边有6,   7,8,9)
    3. 奇数元素组成的数组如果是从 lenght /2 到  length 拆分数组的话得到的是包括中间数组在内的后半截数组。
    4. 偶数元素组成的数组就是从中间偏右的那个元素开始到数组结束了。
  4. 代码
    package learning.Array;
    
    import java.util.Arrays;
    
    public class BinarySearch {
        static int  resultIndex = 0;
        public static void main(String []args){
            int []array1 = {1,2,3,4,5,6,7,8,9};
            BinarySearch binarySearch = new BinarySearch();
            binarySearch.isFinded(array1, 7);
            for (int i = 0; i< array1.length ; i++){
                if(array1[i] == resultIndex){
                    System.out.println(i);
                }
            }
        }
    
        private int isFinded(int []array, int dest){
            int length = array.length;
            if(dest > array[length / 2]){
    //            可以把length理解为数组的元素  “个数”, 那么对于奇数个元素组成的数组,“个数” / 2 得到的是最中间的那一个元素(比如有九个元素, 9 / 2 = 4, 下标为4对应
    //               的就是第五个元素,也就是最中间的哪个元素)
    //            如果是偶数个元素组成的数组, “个数” / 2 得到的是中间偏右的那一个元素(例如有十个元素,length = 10 , 10 / 2 = 5,下标为5的对应的是数组第六个元素,也就
    //               是中间偏右的哪个元素啦)
                isFinded(catHalfArray(array, "big"), dest);
            }else if(dest < array[length / 2]){
                isFinded(catHalfArray(array, "small"), dest);
            }else {
              resultIndex = array[array.length/2];
                return 0;
            }
            return 0;
        }
    
        private int[] catHalfArray(int []array, String bigOrsmall){
            int length = array.length;
            int halflength = length / 2;
    //        这里的除以2的道理也是一样的,如果是奇数个元素的话就会得到从第一个到最中间那个元素(包括最中间那个元素)
    //        的数组(或者是从最中间那个元素开始到最后一个元素)
            if("big".equals(bigOrsmall)){
                int []resultArray = new int[length - halflength];
                for(int i = 0; i < resultArray.length; i++){
                    resultArray[i] =  array[i + halflength];
                }
                return resultArray;
            }else {
                int []resultArray = new int[length - halflength];
                for(int i = 0; i < resultArray.length; i++){
                    resultArray[i] =  array[i];
                }
                return resultArray;
            }
        }
    }
    

     

  5. 代码2

    1. 这个算法是不断地修改声明好的头下标,尾下标和中间下标进行查找的,比上边那个算法时间空间开销比较小

      package learning.Array;
      
      /**
       * 前提:
       *      1、还是那个道理,如果是奇数个元素组成的数组,那么其length / 2 得到的是最中间的那个元素的下标
       *      如果是偶数个元素组成的数组,length / 2 得到的是中间偏右那个元素的下标
       *      2、下边的算法是动态地修改数组的头下标或者尾下标,相当于是新生成了一个新的数组,所以用它的头
       *      下标和尾下标相加除以2和上边那个点得到的效果是一样的。
       *  
       * 算法:
       *      1、定义一个头下标,一个尾下标, 一个中间值下标。
       *      2、每次将目标元素和中间下标对应的数组元素进行对比。
       *          1、如果中间元素比目标元素大的话,就把尾下标修改成目标元素减一,即指向目标元素的左边。
       *          2、如果中间元素比目标元素小的话,就把头下标修改成目标元素加一,即指向目标元素的右边。
       */
      public class BinarySearchByTeacher {
      
          public static  void main(String []args){
              int []  array = {1,2,3,4,5,6,7,8,9};
              int target = 5;
              int begin = 0;
              int end = array.length - 1;
              int mid = (target + end) / 2;
              while(true){
                  if(array[mid] == target){
                      break;
                  }
                  if(array[mid] > target){
                      end = mid - 1;
                  }else {
                      begin = mid + 1;
                  }
                  mid = (begin + end) / 2;
              }
              System.out.println(mid);
          }
      }
      

       

你可能感兴趣的:(数据结构 数组的二分法查找)