- /**
- *
- * @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