美文网首页
循环数组的二分查找--Java实现

循环数组的二分查找--Java实现

作者: J4ckyChan | 来源:发表于2018-11-12 18:05 被阅读0次
/**
 * 循环数组的二分查找
 * @author Jacky
*测试用数组
 *[9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8]
*数组对应下标,方便查看
 *[0,  1,  2,  3, 4,  5,  6,  7,   8,  9, 10, 11,12,13,14,15,16,17,18,19]
 */
public class BSearch2 {
    public static int BSearch(int[] arr,int left,int right,int value) {
        while(left<=right) {
            int mid = left+((right-left)>>1);//防止溢出的取中方法
            if(value<arr[mid]) {
                int lMid = (left+mid)/2;//取左区间的中间值,仅用于判断是否单调增长
                if(arr[0]<=arr[lMid]&&arr[lMid]<=arr[mid]) {//如果此时左区间是单调增长
                    //判断value是否在左边区间,通过与区间另一端的值比较
                    //如果在左边区间
                    if(value>=arr[left]) {
                        //则在左区间做二分查找
                        int result = BSearch(arr,left,mid-1,value);
                        if(result!=-1) return result;//需要对返回值进行判断,否则递归没有出口
                    }else {//如果在右边区间,则要在右区间做二分查找
                        int result = BSearch(arr,mid+1,right,value);
                        if(result!=-1) return result;
                    }
                }else {
                    //在左区间做二分查找
                    int result = BSearch(arr,left,mid-1,value);
                    if(result!=-1) return result;
                }
            }else if(value>arr[mid]) {//同理
                int rMid = (right+mid)/2;
                if(arr[mid]<=arr[rMid]&&arr[rMid]<=arr[right]) {//单调区间
                    if(value<=arr[right]) {//在
                        int result = BSearch(arr,mid+1,right,value);
                        if(result!=-1) return result;
                    }else {//不在
                        int result = BSearch(arr,left,mid-1,value);
                        if(result!=-1) return result;
                    }
                }else {//非单调区间,一定在
                    int result = BSearch(arr,mid+1,right,value);
                    if(result!=-1) return result;
                }
            }else {
                return mid;
            }
        }
        return -1;
    }
    
    public static void main(String[] args) {
        int arr[] = {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8};
        int i = BSearch(arr,0,arr.length-1,8);
        System.out.println(i);
    }
    
}

与普通二分查找的不同:

  1. 以上的查找对象为循环数组,而普通二分查找的对象为有序的普通数组;
  2. 正因为是循环数组,取中进行判断之后,目标值不一定在普通二分查找所设想的区间,需要进行判断,具体判断如下:

如何判断一段数组是单调递增呢?在该段数组的头、中间、尾三个位置p,m,q取三个值a[p], a[m], a[q],如果是单调递增则一定满足 a[p] >= a[m] >= a[q],否则则非单调递增。

判断目标元素下一步所在区间,有几种情况:
当 x > a[m] 时,
右半边是单调递增区间,并且x在此区间内,下一步则可在此右半边区间内查找
右半边是单调递增区间,并且x不在此区间内,下一步在左半边查找
右半边是非单调递增区间,则x必然在此区间内,下一步在右半边查找
当 x < a[m] 时, 同理类似
左半边是单调递增区间,并且x在此区间内,下一步则可在此左半边区间内查找
左半边是单调递增区间,并且x不在此区间内,下一步在右半边查找
左半边是非单调递增区间,则x必然在此区间内,下一步在左半边查找

判断是否在单调递增部分,只需与区间的另外一头的元素比较一下大小即可知道

参考文章:循环有序数组的二分查找

相关文章

  • golang循环递增数组查找值

    循环递增数组查找值 golang 1.实现要求 在循环递增数组中查找某个值 2.实现方法 使用二分法实现查找 使用...

  • 输入一个数组,利用二分法查找

    关于二分法查找Java的实现 对于一维数组的查找我们采用一个for循环遍历一次数组就可以实现,但有时候当数组太大,...

  • 算法 -- 二分查找

    二分查找有两种实现:通过递归或循环 二分查找的前提是先要保证数组有序 递归 循环 github 完整代码 -- b...

  • 二分查找

    概念二分查找又叫折半查找,从排序数组中查找元素的位置。 图示二分查找 Java实现 复杂度T(n)=T(n/2)+...

  • 循环数组的二分查找--Java实现

    与普通二分查找的不同: 以上的查找对象为循环数组,而普通二分查找的对象为有序的普通数组; 正因为是循环数组,取中进...

  • 算法之二分查找

    二分查找 二分查找是著名、高效并有应用广泛的查找算法。 二分常规实现 1.循环实现 下面我用python语言实现循...

  • 二分查找

    网上找到的图片便于理解 二分查找递归实现与循环实现代码: /** 二分查找 1.二分查找又称折半查找,它是一种效率...

  • OC各种算法,排序,查找实现

    二维数组查找数字的OC实现 OC 二分查找的实现 快速排序

  • JavaScript实现二分查找

    最近撸《算法》第四版,开篇就是一个Java版本的二分查找算法,下面以JS实现一下。 二分查找的前提为:数组、有序。...

  • 简单的二分查找算法java实现

    一个二分查找的java实现,查找value 在 有序数组(由小到大)中的 下标。时间复杂度为 O(logn) 执行...

网友评论

      本文标题:循环数组的二分查找--Java实现

      本文链接:https://www.haomeiwen.com/subject/ykgcfqtx.html