倒置数组元素查找--时间复杂度O(lgn)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值