/** * * @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,5]->[4,5,1,3] * 在倒置的数组中查找一个元素 * * 选取mid之后,前后必有一半是有序的。比较low/mid-1和mid+1/high * 这两对位置的值就知道 * 如果num落在有序的一半, * 接下来的查找都变成折半查找;如果num落在无序的一半, * @param arr * @param num * @return */ public static int exBinSearch(int arr[],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,6,7,8,9,10,22,34,56,67,89,100}; int arr2[] = {67,100,56}; int demo[] = {1,11,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