1. 程式人生 > >二分查找算法

二分查找算法

void small == equal 頻繁 pub 分割 下標 一個

二分查找算法是在有序數組中用到較為頻繁的一種算法。如果不使用二分算法直接對數組進行遍歷,跟每個元素進行比較,其時間復雜度為O(n)。 但是二分查找算法則更優,因為其查找的時間復雜度為O(lgn),比如數組{1,2,3,4,5,6,7,8,9}。需要查找元素,用二分查找的算法執行的話,其順序為: 第一步:查找中間元素,即為5。由於5<6,則6必然在5之後的數組元素中,那麽就在{6,7,8,9}查找; 第二步:尋找{6,7,8,9}的中位數,選7。由於7>6,則6應該在7左邊的數組元素中,那麽只剩下6,即找到了。 說白了二分查找法就是不斷將數組進行對半分割,每次拿中間元素和目標值進行比較。 案例一:
package cn.imooc.java2;
public class Test02 {
     //定義一個靜態方法
     static int binarySerach(int[] array, int key) {
          //定義數組下標的最左
         int left = 0;
         //定義數組下標的最右(下標都是從0開始的,因此需要-1)
         int right = array.length - 1;
         while (left <= right) {
             int mid = (left + right) / 2;
             //判斷中間值是否為目標值
             if (array[mid] == key) {
                 return mid;
             }
             else if (array[mid] < key) {
                 left = mid + 1;
             }
             else {
                 right = mid - 1;
             }
         }
         return -1;
     }
    //測試,目標值為7
     public static void main(String[] args) {
          Test02 s = new Test02();
          int[] b={1,5,6,7,8,9,10,12};      
          System.out.println(s.binarySerach(b, 7));
     }
}
註意:每次移動left和right指針的時候,需要在mid的基礎上+1或者-1, 防止出現死循環, 程序也就能夠正確的運行。並且代碼中的判斷條件必須是while (left <= right),否則的話判斷條件不完整,比如:array[3] = {1, 3, 5};待查找的鍵為5,此時在(low < high)條件下就會找不到,因為low和high相等時,指向元素5,但是此時條件不成立,沒有進入while()中。 案例二:查找第一個相等的元素
package cn.imooc.java2;
public class Test02 {
     // 查找第一個相等的元素
     static int findFirstEqual(int[] array, int key) {
         int left = 0;
         int right = array.length - 1;
         while (left <= right) {
             int mid = (left + right) / 2;
             if (array[mid] >= key) {
                 right = mid - 1;
             }
             else {
                 left = mid + 1;
             }
         }
         if (left < array.length && array[left] == key) {
             return left;
         }        
         return -1;
     }
     public static void main(String[] args) {
          Test02 s = new Test02();
          int[] b={1,5,6,7,7,7,7,8,9,10,12};         
          System.out.println(s.findFirstEqual(b, 7));
     }
}

  

案例三:查找最後一個相等的元素
package cn.imooc.java2;
public class Test02 {
     static int findLastEqual(int[] array, int key) {
         int left = 0;
         int right = array.length - 1;
         while (left <= right) {
             int mid = (left + right) / 2;
             if (array[mid] <= key) {
                 left = mid + 1;
             }
             else {
                 right = mid - 1;
             }
         }
         if (right >= 0 && array[right] == key) {
             return right;
         }
         return -1;
     }
     public static void main(String[] args) {
          Test02 s = new Test02();
          int[] b={1,5,6,7,7,7,7,8,9,10,12};         
          System.out.println(s.findLastEqual(b, 7));
     }
}

  

案例四:查找最後一個等於或者小於key的元素。也就是說等於查找key值的元素有好多個,返回這些元素最右邊的元素下標;如果沒有等於key值的元素,則返回小於key的最右邊元素下標。
package cn.imooc.java2;
public class Test02 {
     static int findLastEqualSmaller(int[] array, int key) {
         int left = 0;
         int right = array.length - 1;
         while (left <= right) {
             int mid = (left + right) / 2;
             if (array[mid] > key) {
                 right = mid - 1;
             }
             else {
                 left = mid + 1;
             }
         }
         return right;
     }
     public static void main(String[] args) {
          Test02 s = new Test02();
          int[] b={1,5,6,7,7,7,7,8,9,10,12};         
          System.out.println(s.findLastEqualSmaller(b, 11));
     }
}

案例五:查找第一個等於或者大於key的元素。也就是說等於查找key值的元素有好多個,返回這些元素最左邊的元素下標;如果沒有等於key值的元素,則返回大於key的最左邊元素下標。
package cn.imooc.java2;
public class Test02 {
     static int findFirstEqualLarger(int[] array, int key) {
         int left = 0;
         int right = array.length - 1;
         while (left <= right) {
             int mid = (left + right) / 2;
             if (array[mid] >= key) {
                 right = mid - 1;
             }
             else {
                 left = mid + 1;
             }
         }
         return left;
     }
     public static void main(String[] args) {
          Test02 s = new Test02();
          int[] b={1,5,6,7,7,7,7,8,9,10,12};         
          System.out.println(s.findFirstEqualLarger(b, 11));
     }
}

  

案例六:查找第一個大於key的元素,也就是說返回大於key的最左邊元素下標。
package cn.imooc.java2;
public class Test02 {
     static int findFirstLarger(int[] array, int key) {
         int left = 0;
         int right = array.length - 1;
         while (left <= right) {
             int mid = (left + right) / 2;
             if (array[mid] > key) {
                 right = mid - 1;
             }
             else {
                 left = mid + 1;
             }
         }
         return left;
     }
     public static void main(String[] args) {
          Test02 s = new Test02();
          int[] b={1,5,6,7,7,7,7,8,9,10,12};         
          System.out.println(s.findFirstLarger(b, 11));
     }
}

  

二分查找算法