算法--二分搜索

二分搜索就是在搜索东西时每次都从中间下手,一次排除一半,快速锁定目标。

所以能用二分搜索的数据,都是按一定大小规律排列的

基础版:

java 复制代码
public class BinarySearch {
//    二分查找基础版
    public  static int binarySearchBasic(int[] a,int target) {
        int i =0,j=a.length-1;//设置指针和初值
        while (i<=j){//范围内有东西
            int m = (i+j)/2;
            if(target < a[m]){//目标在左边
                j = m-1;
            } else if (target > a[m]) {//目标在右边边
                i = m+1;
            }else  {//找到了
                return m;
            }
        }
        return -1;
    }
    
}

while循环中用<=而不用<号的原因:因为在两个指针重合时,即:i=j,会直接返回-1。如此数据在这种情况就查不出来了

不用等号的原因也与a.length-1有关

int m = (i+j)/2;可能遇到的问题:在数字太大的情况下会导致溢出变成负数。所以可以改为>>>1符号

改动版:

java 复制代码
//    二分查找改动版
    public static int binarySearchAlternative(int[] a,int target) {
        int i =0,j=a.length;  //第一处
        while (i<j){  //第二处
            int m = (i+j)>>>1;
            if(target < a[m]){
                j = m; //第三处
            } else if (a[m] < target) {
                i = m+1;
            }else  {
                return m;
            }
        }
        return -1;
    }

平衡版:

java 复制代码
//   二分查找均衡版
    public static int binarySearchBalance(int[] a,int target) {
        int i =0,j=a.length;
        while (1<j-i){
            int m = (i+j)>>>1;
            if(target < a[m]){
                j = m;
            } else if{
                i = m;
            }
        }
        if(a[i] == target){
            return i;
        }else {
            return -1;
        }
        }
    }

优点:减少循环内的平均比较次数(在数据量大时才能体现到)

java中的二分查找:

java 复制代码
 public static int binarySearch(int[] a, int key) {
        return binarySearch0(a, 0, a.length, key);
    }

    /**
     * Searches a range of
     * the specified array of ints for the specified value using the
     * binary search algorithm.
     * The range must be sorted (as
     * by the {@link #sort(int[], int, int)} method)
     * prior to making this call.  If it
     * is not sorted, the results are undefined.  If the range contains
     * multiple elements with the specified value, there is no guarantee which
     * one will be found.
     *
     * @param a the array to be searched
     * @param fromIndex the index of the first element (inclusive) to be
     *          searched
     * @param toIndex the index of the last element (exclusive) to be searched
     * @param key the value to be searched for
     * @return index of the search key, if it is contained in the array
     *         within the specified range;
     *         otherwise, <code>(-(<i>insertion point</i>) - 1)</code>.  The
     *         <i>insertion point</i> is defined as the point at which the
     *         key would be inserted into the array: the index of the first
     *         element in the range greater than the key,
     *         or {@code toIndex} if all
     *         elements in the range are less than the specified key.  Note
     *         that this guarantees that the return value will be &gt;= 0 if
     *         and only if the key is found.
     * @throws IllegalArgumentException
     *         if {@code fromIndex > toIndex}
     * @throws ArrayIndexOutOfBoundsException
     *         if {@code fromIndex < 0 or toIndex > a.length}
     * @since 1.6
     */
    public static int binarySearch(int[] a, int fromIndex, int toIndex,
                                   int key) {
        rangeCheck(a.length, fromIndex, toIndex);
        return binarySearch0(a, fromIndex, toIndex, key);
    }

    // Like public version, but without range checks.
    private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                     int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }

low是插入点

最后return -(low + 1);的意思是找不到这个数,但是可以在这个索引插入数据

java中0与-0是一个数

java 复制代码
//验证类
int[] a ={2,5,8};
int target =4;

int i = Arrays.binarySearch(a,target);
System.out.println(i);

if(i<0){
int insertIndex = Nath.abs(i + 1);
int [] b = new int[a.length + 1];
System.arraycopy(a,0,b,insertIndex);
b[insertIndex] = target;
System.arraycopy(a,insertIndex,b,insertIndex+1,a.length-insertIndex);
System.out.println(Arrays.toString(b));
}
//这样可以把没有检索到的数据添加上去

Leftmost:

java 复制代码
  public static int binarySearchLeftMost(int[] a,int target) {
        int i =0,j=a.length-1;
        int candidate = -1;
        while (i<=j){
            int m = (i+j)>>>1;
            if(target < a[m]){
                j = m-1;
            } else if (a[m] < target) {
                i = m+1;
            }else{
                //记录候选位置
                candate = m;
                j=m - 1;
            }
        }
        return candidate;
    }
    }

寻找重复元素中最靠左的元素

rigntmost:

java 复制代码
public static int binarySearchLeftMost(int[] a,int target) {
    int i =0,j=a.length-1;
    int candidate = -1;
    while (i<=j){
        int m = (i+j)>>>1;
        if(target < a[m]){
            j = m-1;
        } else if (a[m] < target) {
            i = m+1;
        }else{
            //记录候选位置
            candate = m;
            j=m - 1;
        }
    }
    return candidate;
}
    }

与Leftmost代码类似,只不过是寻找重复元素中最靠右的元素

相关推荐
罗西的思考12 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队15 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
像我这样帅的人丶你还16 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩16 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia16 小时前
Mybatis的日志输入
java
亦暖筑序18 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户2986985301421 小时前
Java 实现 Word 文档加密与权限解除
java·后端
Yeats_Liao1 天前
14:Servlet中的页面跳转-Java Web
java·后端·架构
未秃头的程序猿1 天前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
鹤望兰6751 天前
字节跳动国际支付-后端开发-三面面经
java