/** * * @author jiadongkai * @date Dec 2, 2011 * */public class BinSearch { /** * 有序數組[1,2,3,4,5] * 折半尋找arr數組中num的index,不存在返回-1 * @param arr * @param num * @return */ public static int binSearch(int[] arr, int num){ int low = 0, high = arr.length-1; int mid = 0; while(low <= high){ count++; mid = (low+high)/2; if(arr[mid] == num) return mid; if(arr[mid] < num)//合適的位置在後半部分 low = mid + 1; else //合適的位置在前半部分 high = mid - 1; } return -1; } static int count ; /** * [1,2,3,4,5]->[4,5,1,2,3] * 在倒置的數組中尋找一個元素 * * 選取mid之後,前後必有一半是有序的。比較low/mid-1和mid+1/high * 這兩對位置的值就知道 * 如果num落在有序的一半, * 接下來的尋找都變成折半尋找;如果num落在無序的一半, * @param arr * @param num * @return */ public static int exBinSearch(int arr[], int num){ int low = 0, high = arr.length-1; int mid = 0; //用於標記num是否已經進入有序那一半 //若進入,則下次直接使用折半尋找的邏輯 boolean flag = false; while(low <= high){ count++; mid = (low + high)/2; if(arr[mid] == num) return mid; if( !flag && (arr[low] <= arr[mid-1])){ //若前半部分有序 if((arr[low] <= num) && (num <= arr[mid-1])){ //若num落在有序的前半部分 System.out.println("進入有序數組:"+(low)+" -> "+(mid-1)); flag = true; high = mid -1; }else{ //若num落在後半部分 low = mid + 1; } continue; } if( !flag && arr[mid+1] <= arr[high]){ //若後半部分有序 if( (arr[mid+1] <= num) && (num <= arr[high])){ //若num落在有序的後半部分 System.out.println("進入有序數組:"+(mid+1)+" -> "+high); flag = true; low = mid+1; }else{ //若num落在無序的前半部分 high = mid - 1; } continue; } //能運行下面的邏輯,必然是已經確定num落在有序的部分了 if( arr[mid] < num ) low = mid + 1; else high = mid - 1; } return -1; } public static void main(String args[]){ int arr[] = {1,3,5,6,7,8,9,10,22,34,56,67,89,100}; int arr2[] = {67,89,100,1,3,5,6,7,8,9,10,22,34,56}; int demo[] = {1,3,5,11,100,56,90,1000}; for(int i : demo){ System.out.println("---------比較i="+i+"-------------"); System.out.println( i + "的index:" + binSearch(arr, i) ); System.out.println("比較次數:"+count); count=0; System.out.println( i + "的index:" + exBinSearch(arr2, i)); System.out.println("比較次數:"+count); } }}
//~~~~
---------比較i=1-------------
1的index:0
比較次數:3
進入有序數組:3 -> 3
1的index:3
比較次數:4
---------比較i=3-------------
3的index:1
比較次數:8
3的index:4
比較次數:3
---------比較i=5-------------
5的index:2
比較次數:5
5的index:5
比較次數:4
---------比較i=11-------------
11的index:-1
比較次數:8
進入有序數組:7 -> 13
11的index:-1
比較次數:4
---------比較i=100-------------
100的index:13
比較次數:8
100的index:2
比較次數:2
---------比較i=56-------------
56的index:10
比較次數:4
進入有序數組:7 -> 13
56的index:13
比較次數:4
---------比較i=90-------------
90的index:-1
比較次數:8
90的index:-1
比較次數:4
---------比較i=1000-------------
1000的index:-1
比較次數:8
1000的index:-1
比較次數:4