算法--二分搜索

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

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

基础版:

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代码类似,只不过是寻找重复元素中最靠右的元素

相关推荐
小肝一下1 分钟前
3. 单链表
c语言·数据结构·c++·算法·leetcode·链表·dijkstra
劈星斩月8 分钟前
监督学习算法 之 决策树
学习·算法·决策树
学计算机的计算基13 分钟前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法
tachibana217 分钟前
hot100 前 K 个高频元素(347)
java·数据结构·算法·leetcode
AOwhisky19 分钟前
Python 学习笔记(第五期)——组合数据类型:列表、元组、集合与字典精讲——核心知识点自测与详解
开发语言·笔记·python·学习·云计算
woshihuanglaoshi34 分钟前
数据迁移与版本管理 - Flutter在鸿蒙平台实现数据库升级策略
数据库·学习·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
万亿少女的梦16836 分钟前
基于Spring Boot、Java与MySQL的网络订餐系统设计与实现
java·spring boot·mysql·系统设计·网络订餐
To_OC8 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
咩咩啃树皮9 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
旖-旎9 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题