二分查找的非递归、递归实现及其优化

/**
 * 二分查找的非递归、递归实现及其优化
 * 算法要求序列有序
 * 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 = {1,2,3,4,4,5};
        System.out.println(chop(n, 5));
        System.out.println(chop2(n, 5,0,n.length-1));
        System.out.println(chop3(n, 5));
        System.out.println(chop4(n, 5));
    }

    /**
     * 非递归实现
     * 找到时返回下标,找不到时返回-1
     * @param array 目标数组(递增数组)
     * @param point 需要查找的数字
     * @return
     */
    public static int chop(int[] array,int point){
        if(array.length==0||array==null) return -1;  //处理空数组和空指针
        else{
            int low = 0,high = array.length-1,num = -1;
            while(low<=high){
                int mid = (low+high)/2;              //取中点
                if(array[mid]==point){
                    num = mid;
                    break;
                }else if(array[mid]<point) low=mid+1;   //中点右移
                else high=mid-1;                        //中点左移
            }
            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)/2;
        if(low>high||point<array[low]||point>array[high]) return -1;
        if(array[mid]==point) return mid;
        else if(array[mid]>point) return chop2(array, point, low, high-1);
        else return chop2(array, point, low+1, 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==0||array==null) return -1;  //处理空数组和空指针
        else{
            int low = 0,high = array.length-1,num = -1;
            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+1;   //中点右移
                else high=mid-1;                        //中点左移
            }
            return num;
        }
    }

    /**
     * 优化2:斐波那契查找
     * @param array
     * @param point
     * @return
     */
    public static int chop4(int[] array,int point){
        int [] F = {0,1,1,2,3,5,8,13,21,34};     //构造斐波那契数列
        int low, high, mid, k,n=array.length-1;  //n为待查找数组的长度
        low = 1;
        high = n;
        k = 0;
        while (n > F[k]-1) /* 计算n位于斐波那契数列的位置 */
            k++;
        while (low <= high) {
            mid = low + F[k-1] -1;
            if (point < array[mid]){
                high = mid - 1;
                k = k - 1;
            }
            else if (point > array[mid]){
                low = mid + 1;
                k = k - 2;
            }
            else {
                if (mid <= n)
                    return mid;
                else
                    return n;
            }
        }
        return 0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值