对于一个有序数组,我们通常采用二分查找的方式来定位某一元素,请编写二分查找的算法,在数组中查找指定元素。
给定一个整数数组A及它的大小n,同时给定要查找的元素val,请返回它在数组中的位置(从0开始),若不存在该元素,返回-1。若该元素出现多次,请返回第一次出现的位置。
测试样例:
 [1,3,5,7,9],5,3
返回:1
import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        // write code here
        int low=0,higth=n,res=-1;
        while (low != higth){
            int mid = (low + higth)/2;
            if (A[mid] > val){
                higth = mid;
            }else if (A[mid] < val){
                low = mid;
                if (res != -1){
                    break;
                }
            }else {
                res = mid;
                higth = mid;
            }
        }
        return res;
    }
} import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        int left = 0;
        int right = n - 1;
        int mid = 0;
        while(left <= right){
            mid = (left + right) / 2;
            if(A[mid] > val){
                right = mid - 1;
            }else if(A[mid] < val){
                left = mid + 1;
            }else{
                while(mid >= 0){
                    if(A[mid] != val){
                        return mid + 1;
                    }else{
                        mid --;
                    }
                }
                return mid + 1;
            }
        }
        return -1;
    }
} import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        int first = 0, last = n,mid;//n
        while(first < last){
            if(A[0]==val) 
                //经过观察,这种写法仅在第一个位置是val时输出错误,所以单独处理
                return 0;
            mid = first + (last-first)/2;
            if(A[mid]<val){
                first = mid + 1;
            }
            else if(A[mid]==val){
                return mid;
            }
            else
                last = mid;
        }
        return -1;
           
        
    }
} import java.util.*;
public class BinarySearch 
{
    public int getPos(int[] A, int n, int val) 
    {
        return getIndex(A,0,A.length-1,val);
    }
    private int getIndex(int [] arr,int left,int right,int target)
    {
        if(left>right)//说明递归查找完整个数组,还没有找到
        {
            return -1;
        }
        int midIndex=(left+right)/2;
        int midValue=arr[midIndex];
        if(target>midValue)//如果你要找的数比中间的数大,就去右边找
        {
            return getIndex(arr,midIndex+1,right,target);
        }
        else if(target<midValue)//如果你要找的数比中间的数小,就去左边找
        {
            return getIndex(arr,left,midIndex-1,target);
        }
        else
        {
            while(midIndex>left&&arr[midIndex-1]==target)
            {
                midIndex=midIndex-1;
                return midIndex;
            }
            return midIndex;
        }
    }
}
                                                                                    找到第一个比val小的数,res++就是第一个val出现的下标了,如果不是则证明val不存在
 public int getPos(int[] A, int n, int val) {
        int left=0;
        int right=n-1;
        int m;
        int res=-1;
        while(left<=right){
             m=(left+right)/2;
             if(A[m]<val){
                 res=m;
                 left=m+1;
             }else{
                 right=m-1;
             }
        }
        res++;
        if(res>=n||A[res]!=val) return -1;
        else return res;
    }
import java.util.*;
public class BinarySearch {
    public int getPos(int[] a, int n, int value) {
        // write code here
        int middle;
        int left = 0;
        int right = n - 1;
        while (left <= right) {
            middle = (left + right) / 2;
            if (a[middle] > value) {
                right = middle - 1;
            }
            else if (a[middle] < value) {
                left = middle + 1;
            }
            else {
                //return middle;
                //如果出现多次value,
                //遍历一下数组a获得第一个value的数组下标返回即可
                for (int i = 0; i < n; i++) {
                    if (a[i] == value) {
                        return i;
                    }
                }
            }
        }
        return -1;
    }
}
import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        // write code here
        int start=0;
        int end=A.length;
        int mid=(start+end)/2;
        while(start<=end) {
            if(A[mid]==val) {
                return mid;
            }
            if(A[mid]<val) {
                start=mid+1;
            }else if(A[mid]>val){
                end=mid-1;
            }
            mid=(start+end)/2;
        }
        return -1;
    }
}
 //指定值第一次出现
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        int left = 0;
        int right = n-1;
        int center =(left+right)/2;
        while(left<right){
            if(A[center]>=val){//1、为什么这里取等放入
                right = center;
            }
            else{//2、为什么不在这边放置等于的情况
                left = center+1;
            }  
            //3、center赋值位置放这和放循环开始处什么区别
            //4、当取最后一次出现的位置,我这里一般改成(left+right+1)/2
            //5、当取最后一次出现的位置,除了4处修改,对于1、2取等和right left赋值都有些许变化
            center = (left+right)/2;
        }
        return A[center]==val?center:-1;
    }
}
 public class BinarySearch {     public int getPos(int[] A, int n, int val) { // write code here
int start=0;
int end=A.length-1;
        while(start+1<end){ int mid = (start+end)/2;
            if(val==A[mid]){ end=mid;
            }else if(val>A[mid]){ start=mid;
            }else if(val<A[mid]){ end=mid;
}
}
        if(A[start]==val){ return start;
}
        if(A[end]==val){ return end;
}
return -1;
}
}
// Java 典型的 二分查找(递归做法)
    public int getPos(int[] A, int n, int val) {
        if (A == null || A.length <= 0)
            return -1;
        return getPos(A, 0, A.length-1, val);
    }
    private int getPos(int[] A, int low, int high, int val) {
        if (low > high)
            return -1;
        int mid = (low + high) >> 1;
        if (A[ mid ] == val && (mid == low || A[ mid - 1 ] != val))
            return mid;
        else if (A[ mid ] >= val)
            return getPos(A, low, mid - 1, val);
        else
            return getPos(A, mid + 1, high, val);
    }
// Java非递归 的二分查找
    public int getPos(int[] A, int n, int val) {
        if (A == null || A.length <= 0)
            return -1;
        int mid, low = 0, high = A.length - 1;
        while (low <= high) {
            mid = (low + high) >> 1;
            if (A[ mid ] == val && (mid == low || A[ mid-1 ] != val))
                return mid;
            else if (A[ mid ] >= val)
                high = mid - 1;
            else low = mid + 1;
        }
        return -1;
    }  注意这里当找到时不能直接返回,而是用一个标志位标志,然后再重新遍历一次数组找到第一次出现 的位置。
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        if(n<=0)
            return -1;
        int res=getk(0,n-1,A,val);
        return res;    
    }
    public int getk(int start ,int end ,int[] a,int val)
        {
        int mid=(start+end)/2;
        int num=a[mid];
    
        if(num>val)
            {
            end=mid;
            return getk(0,mid,a,val);
        }
        else if(num<val)
            {
            start=mid+1;
            return getk(mid+1,end,a,val);
        }
        else
            {
             if(mid==0)
                 return mid;
           for(int i=1;i<=mid;i++)
                {
                if(a[mid-i]==val)
                    return (mid-i);
                 else
                    return mid;
              }
        }
       return -1;
    }
}
package HaoWeiLai;
import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
		int lo=0, hi=n;
        int target =search(A, lo, hi, val);
        if(target==n)
            return -1;
		return A[target] == val? target:-1;
    }
    public static int search(int[] A, int lo, int hi, int val){
    	int mid;
    	while(hi-lo>0){
    		mid = (lo+hi)>>1;
    		if(A[mid] < val){
    			lo = mid+1;
    		}else if ( val <=A[mid]){
    			hi = mid;
    		}
    	}
    	return lo;
    	
    }
}
import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        // write code here
        int begin = 0;
        int end = n-1;
        int mid = (begin+end)/2;
        while(begin<=end){
            if(val>A[mid]){
                begin = mid+1;
            }else if (val == A[mid]){
               if(mid>=1&&val==A[mid-1]){
                    end = mid-1;
                }else {
                    return mid;
                }
            }else {
                end = mid-1;
            }
            mid = (begin+end)/2;
        }
        return -1;
    }
}
package com.ginto.practise010;
import java.util.Scanner;
public class BinarySearch {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int[] A;
		int n;
		int val;
		System.out.print("输入数组大小:");
		n=scanner.nextInt();
		A=new int[n];
		System.out.print("输入数组元素:");
		for(int i=0;i<n;i++){
			A[i]=scanner.nextInt();
		}
		System.out.print("输入需要查找的元素:");
		val=scanner.nextInt();
		BinarySearch bs=new BinarySearch();
		System.out.println(bs.getPos(A, n, val));
	}
	 public int getPos(int[] A, int n, int val) {
	    int low=0;
	    int middle;
	    int high=A.length-1;
	    while(low<=high){
	    	middle=low+((high-low)>>1);
	    	
	    	if(A[middle]==val&&A[low]==A[middle]){
	    		return low;
	    	}else if(A[middle]==val){
	    		return middle;
	    	}else if(A[middle]>val){
	    		high=middle-1;
	    	}else{
	    		low=middle+1;
	    	}
	    }
	    return -1;
	 }
}
只考虑升序的解法如下,降序数组依次类推即可。
import java.util.*;
public class BinarySearch {
    public int getPos(int[] A, int n, int val) {
        // write code here
        int low = 0;
        int high = n;
        int mid = 0;
        while(low < high){
            mid = (low + high)/2;
            if(val <= A[mid]){
                high = mid;
            }else if(val > A[mid]){
                low = mid+1;
            }
        }
        if(val == A[low]){
            return low;
        }else{
            return -1;
        }
    }
}