基于数组二分查找算法的实现

基于数组二分查找算法的实现

二分查找 查找 算法 赵振江

二分查找又称折半查找,优点是比较次数,查找速度,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

一张图片说明过程

Alt text

普通版本的二分查找

时间复杂度是O(N)

//基于数组的普通的二分查找法,非递归
    public static int binaryChop(int[] arr,int n){
        int low=0;//表示数组左边界,或者你分割后的左边界,你也可以声明它为left。
        int up=arr.length;//表示数组右边界,或者你分割后的右边界,你也可以声明它为right。
        int mid=0;//已经锁定数组的中间值
        //开始二分查找
        while(low<up){//循环结束条件,当左边界超过右边界时候,也就是说没有找到目标值
            mid=(low+up)/2;//找到中间值,不要问我为什么是(low+up)/2自己想!V_V
            if(n<arr[mid])//如果中间值比目标值要大,砍掉数组的右边部分。
                up=mid-1;
            else if(n>arr[mid])//如果中间值比目标值要小,砍掉数组的左边部分。
                low=mid+1;
            if(arr[mid]==n)//巧了,正好好就是这个中间值(这是幸运情况,大部分是,靠,终于找到你了)
                return mid;
        }
        return NO_VALUE;
    }

递归版本的二分查找时间

复杂度是O(logN)

//基于数组的二分查找法,递归版本偶!
    public static int binaryChopRecursive(int[] arr,int n,int low,int up){
        int mid=(low+up)/2;
        //递归结束基值(不要问什么是基值,这是术语,其实就是递归总有一个结束的条件)
        if(low>up)
            return NO_VALUE;
        if(n<arr[mid])//如果中间值比目标值要大,砍掉数组的右边部分。
            up=mid-1;
        else if(n>arr[mid])//如果中间值比目标值要小,砍掉数组的左边部分。
            low=mid+1;
        if(arr[mid]==n)//巧了,正好好就是这个中间值(这是幸运情况,大部分是,靠,终于找到你了)
            return mid;
        return binaryChopRecursive(arr, n, low, up);
    }

完整的代码,Search类和一个测试类

Search.java

package Search;
/**
 * 
 * @author River(赵振江)
 *
 */

public class Search {
    //定义一个静态变量,表示没有找到目标值
    public static final int NO_VALUE=-1;

    //----------------------------------------------
    //----------------二分查找法!----------------------
    //----------------------------------------------
    //二分查找法,在一个有序列中快速索引到一个值
    //注意,名字很有意思,binary:二分 chop:劈、砍,这是很形象的^_^
    //----------------------------------------------

    //基于数组的普通的二分查找法,非递归
    public static int binaryChop(int[] arr,int n){
        int low=0;//表示数组左边界,或者你分割后的左边界,你也可以声明它为left。
        int up=arr.length;//表示数组右边界,或者你分割后的右边界,你也可以声明它为right。
        int mid=0;//已经锁定数组的中间值
        //开始二分查找
        while(low<up){//循环结束条件,当左边界超过右边界时候,也就是说没有找到目标值
            mid=(low+up)/2;//找到中间值,不要问我为什么是(low+up)/2自己想!V_V
            if(n<arr[mid])//如果中间值比目标值要大,砍掉数组的右边部分。
                up=mid-1;
            else if(n>arr[mid])//如果中间值比目标值要小,砍掉数组的左边部分。
                low=mid+1;
            if(arr[mid]==n)//巧了,正好好就是这个中间值(这是幸运情况,大部分是,靠,终于找到你了)
                return mid;
        }
        return NO_VALUE;
    }

    //基于数组的二分查找法,递归版本偶!
    public static int binaryChopRecursive(int[] arr,int n,int low,int up){
        int mid=(low+up)/2;
        //递归结束基值(不要问什么是基值,这是术语,其实就是递归总有一个结束的条件)
        if(low>up)
            return NO_VALUE;
        if(n<arr[mid])//如果中间值比目标值要大,砍掉数组的右边部分。
            up=mid-1;
        else if(n>arr[mid])//如果中间值比目标值要小,砍掉数组的左边部分。
            low=mid+1;
        if(arr[mid]==n)//巧了,正好好就是这个中间值(这是幸运情况,大部分是,靠,终于找到你了)
            return mid;
        return binaryChopRecursive(arr, n, low, up);
    }
    //----------------------------------------------
    //-----------------The end 二分查找法---------------
    //-----------测试类是BinaryChopTest.java-----------
    //----------------------------------------------

}

BinaryChopTest.java

package SearchTests;

public class BinaryChopTest {
    //测试二分查找法
    public static void main(String[] args) {
        //初始化一个数组,注意是个有序数组
        int[] myArr={1,2,3,4,5,6,7,8};
        //定义两个结果变量,这里直接把要查找的值代入函数,如果你是强迫症你也可以用Scanner类从键盘录入^_^
        int result1=Search.binaryChop(myArr, 3);
        int result2=Search.binaryChopRecursive(myArr, 8, 0, myArr.length);
        if(result1!=-1&&result2!=-1){
            System.out.println("查找成功!"+myArr[result1]+"在数组的"+result1+"位置");
            System.out.println("递归版,查找成功!"+myArr[result2]+"在数组的"+result2+"位置");
        }
        else
            System.out.println("没有查找到!");
    }

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值