比较简单,就不介绍了,代码中也有介绍与说明。
/**
*@Title: BinarySearch.java
*@Package sortandsearch
*@Description: TODO
*@author peidong
*@date 2017-5-5 上午9:16:33
*@version V1.0
*/
packagesortandsearch;
/**
* @ClassName: BinarySearch
* @Description: 一些与二分查找相关的问题
* @date 2017-5-5 上午9:16:33
*
*/
publicclass BinarySearch {
/*问题1描述
给一个已经排序的数组,其中有N个互不相同的元素。要求使用最小的比较次数找出其中的一个元素。
(你认为二分查找在排序数组里找一个元素是最优的算法的吗?)*/
/**
*
* @Title: binarySearch
* @Description: 最基础的二分查找
* @param @param arr 数组
* @param @param start 开始位置
* @param @param end 结束位置
* @param @param key 查找的值
* @param @return
* @return int
* @throws
*/
public static int binarySearch(int[] arr,int start, int end, int key){
int mid;
while(start <= end){
mid = (start + (end -1))/2;
//第一次比较
if(arr[mid] == key)
return mid;
//第二次比较
if(arr[mid] > key)
end = mid - 1;
//第三次比较
else
start = mid +1;
}
return -1;
}
/*理论上,我们最多需要 logN+1 次比较。仔细观察,我们在每次迭代中使用两次比较,除了最后比较成
功的一次。实际应用上,比较也是代价高昂的操作,往往不是简单的数据类型的比较。减少比较的次数也是
优化的方向之一。*/
/**
*
* @Title: binarySearch2
* @Description: 改进的二分查找
* @param arr
* @param start
* @param end
* @param key
* @return
* @return int
* @throws
*/
public static int binarySearch2(int[]arr, int start, int end, int key){
int mid;
while(end - 1 >start){
mid = start + (end-1)/2;
if(arr[mid] <= key){
start = mid;
}else
end = mid;
}
if(arr[start] == key)
return start;
else
return -1;
}
/*问题2描述
给一个有N个互不相同的元素的已排序数组,返回小于或等于给定key的最大元素。 例如输入为 A = {-1, 2, 3, 5, 6, 8, 9, 10} key = 7,应该返回6.
分析:
我们可以用上面的优化方案,还是保持一个恒等式,然后移动左右两个指针。最终 left指针会指向 小于或等于给定key的最大元素(根据恒等式A[l] <= key and A[r] > key)。
- > 如果数组中所有元素都小于key,左边的指针left 会一直移动到最后一个元素。
- > 如果数组中所有元素都大于key,这是一个错误条件,无答案。
- > 如果数组中的所有元素都 <= key,这是最坏的情况根据下面的实现*/
public static int floor(int[] arr, intstart, int end, int key){
int mid;
while(end - 1 > start){
mid = start + (end -1)/2;
if(arr[mid] <= key)
start = mid;
else
end = mid;
}
return arr[start];
}
//首次调用
public static int floor(int[] arr, intlen, int key){
//如果key比所有值都小
if(key < arr[0])
return -1;
//递归
return floor(arr, 0, len, key);
}
/**
*@Title: main
*@Description: 测试
*@param @param args
*@return void
*@throws
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//问题一测试用例
// int[] arr = {1,2,3,4,5,6,7,8,9};
// int res1,res2;
// res1 = binarySearch(arr,0,9,5);
// res2 = binarySearch2(arr, 0, 5, 7);
// System.out.printf("%d,%d",res1,res2);
//问题二测试用例
int[] arr1 = {-1, 2, 3, 5, 6, 8, 9,10};
int res;
res = floor(arr1, 7, 7);
System.out.println(res);
}
}