二分查找

package demo1;
/**
 * 
 * @author 高硕
 * 1.二分查找
 * 2.二分查找指定值,返回其第一次出现的位置
 *
 */
public class Example1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array = {1,2,3,3,4,5,6};
		int des=3;
		int item=binarySearchfirst(array,des);
		System.out.println(item);
	}


	public static int binarySearch(int[] array, int target) {
		//普通的方法,标准的二分查找,不涉及到重复数据,以及返回第一次出现的位置
	    //定义初始最小、最大索引
	    int start = 0;
	    int end = array.length - 1;
	    //确保不会出现重复查找,越界
	    while (start <= end) {
	        //计算出中间索引值
//	    	int mid = low + ( high - low ) / 2;
	        int middle = (end + start)>>>1 ;//防止溢出
//	        System.out.println(middle);
	        if (target == array[middle]) {
	            return middle;
	        //判断下限
	        } else if (target < array[middle]) {
	            end = middle - 1;
	        //判断上限
	        } else {
	            start = middle + 1;
	        }
	    }
	    //若没有,则返回-1
	    return -1;
	}
	

	public static int binarySearchfirst(int[] array, int target) {
		//功能:若该元素出现多次,请返回第一次出现的位置。
		int start = 0;
		int end =array.length-1;
		int flag = -1;
		
		while (start<=end) {
			int middle = start+(end-start)/2;
			
			if (target==array[middle]) {
				flag = middle;
			}
			// 如果中间值大于等于给定值,指针的最高位移动,之所以这里要用等于,
			// 就是因为此处会存在最低位出现重复元素的情况,比如4,4,10,21
			// mid第一次指向第二个4,但是第二个4并不是答案,所以high还需要移动,
			// 这样原先的flag的值就会被覆写。
			if (target<=array[middle]) {
				end = middle-1;
			}
			// 如果中间值小于给定值,最低位移动,此处是不可以用等号的,此处如果用等号
			// 就会导致第一个重复元素的下标为奇数(下标从0开始)的循环条件 low>high,
			// 最终结果错误。
			if (target>array[middle]) {
				start = middle+1;
			}
		}
		// 此处直接返回flag即可,不用做判断,如果数组中没有给定值,flag还是初始值-1;
		// 如果有给定值,flag进行了重新赋值,所以无需判断。
		return flag;
	}

}

 

你可能感兴趣的:(算法基础)