/**
* 二分查找的非递归、递归实现及其优化
* 算法要求序列有序
* 1、折半查找是进行加法与除法运算的(mid=(low+high)/2)
* 2、插值查找则进行更复杂的四则运算(mid = low + (high - low) * ((key - a[low]) / (a[high] - a[low])))
* 3、而斐波那契查找只进行最简单的加减法运算(mid = low + F[k-1] - 1),在海量数据的查找过程中,这种细微的差别可能会影响最终的效率。
* 因此就执行效率来说3>1>2
* @author fwk
*/
public class BinaryChop {
public static void main(String[] args) {
int [] n = {,,,,,};
System.out.println(chop(n, ));
System.out.println(chop2(n, ,,n.length-));
System.out.println(chop3(n, ));
System.out.println(chop4(n, ));
}
/**
* 非递归实现
* 找到时返回下标,找不到时返回-1
* @param array 目标数组(递增数组)
* @param point 需要查找的数字
* @return
*/
public static int chop(int[] array,int point){
if(array.length==||array==null) return -; //处理空数组和空指针
else{
int low = ,high = array.length-,num = -;
while(low<=high){
int mid = (low+high)/; //取中点
if(array[mid]==point){
num = mid;
break;
}else if(array[mid]<point) low=mid+; //中点右移
else high=mid-; //中点左移
}
return num;
}
}
/**
* 递归实现二分查找
* @param array
* @param point
* @param low
* @param high
* @return
*/
public static int chop2(int[] array,int point,int low,int high){
//注:此处也应做数组非空检查
int mid = (low+high)/;
if(low>high||point<array[low]||point>array[high]) return -;
if(array[mid]==point) return mid;
else if(array[mid]>point) return chop2(array, point, low, high-);
else return chop2(array, point, low+, high);
}
/**
* 优化1:插值查找
* 插值查找算法对二分查找算法的改进主要体现在mid的计算上
* 计算公式为:mid = ((point-array[low])/(array[high]-array[low]))*(high-low)+low
* @param array
* @param point
* @return
*/
public static int chop3(int[] array,int point){
if(array.length==||array==null) return -; //处理空数组和空指针
else{
int low = ,high = array.length-,num = -;
while(low<high){
int mid = ((point-array[low])/(array[high]-array[low]))*(high-low)+low;
if(array[mid]==point){
num = mid;
break;
}else if(array[mid]<point) low=mid+; //中点右移
else high=mid-; //中点左移
}
return num;
}
}
/**
* 优化2:斐波那契查找
* @param array
* @param point
* @return
*/
public static int chop4(int[] array,int point){
int [] F = {,,,,,,,,,}; //构造斐波那契数列
int low, high, mid, k,n=array.length-; //n为待查找数组的长度
low = ;
high = n;
k = ;
while (n > F[k]-) /* 计算n位于斐波那契数列的位置 */
k++;
while (low <= high) {
mid = low + F[k-] -;
if (point < array[mid]){
high = mid - ;
k = k - ;
}
else if (point > array[mid]){
low = mid + ;
k = k - ;
}
else {
if (mid <= n)
return mid;
else
return n;
}
}
return ;
}
}