算法--二分搜索

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

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

基础版:

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

相关推荐
aichitang20243 分钟前
希尔伯特空间中的正交性
人工智能·学习·机器学习·ai·泛函分析
for_ever_love__3 分钟前
python基础语法学习: 正则表达式
python·学习·正则表达式
hetao173383713 分钟前
2026-08-27~29 hetao1733837 的刷题记录
c++·算法
佳児素花痴╮13 分钟前
STM32U575RIT6(USART)学习
stm32·嵌入式硬件·学习
格林威18 分钟前
C# 相机Burst模式图像采集:使用相机内存配合OpenCvSharp和Halcon实现短时间的高速采集的方法
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
sunshine22 girl18 分钟前
Angular7,9,学习笔记三 dom操作
笔记·学习·angular
chen<>26 分钟前
C++ 六种 memory_order:从原子性到线程间可见性.md
java·linux·开发语言·c++
一直C28 分钟前
Linux系统编程|进程间通信IPC全套详解(1)(管道、信号)
linux·c语言·开发语言·网络·青少年编程·visual studio code
十年Java程序媛29 分钟前
SpringBoot3 + JDK17 实战复盘:HikariCP 连接耗尽,虚拟线程场景额外注意事项
java·spring boot
云淡风轻~窗明几净31 分钟前
宇宙管理学猜想
算法·图论