算法--二分搜索

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

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

基础版:

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

相关推荐
zs宝来了2 小时前
网络篇15-网络收发包应用之iptable
开发语言·网络·php
编码浪子2 小时前
《安全 Rust 的边界在哪?》— 中文解读
开发语言·安全·rust
逍遥德2 小时前
MQTT教程详解-03. 高级知识点
java·物联网·中间件·信息与通信·iot·iotdb
kyriewen112 小时前
Next.js:让你的React应用从“裸奔”到“穿衣服”
开发语言·前端·javascript·react.js·设计模式·ecmascript
代码丰2 小时前
Github高赞项目50K learn-claude-code 的学习笔记总结
笔记·学习·github
Nice__J2 小时前
ISO26262功能安全——SafeOS
java·linux·安全
三品吉他手会点灯2 小时前
C语言学习笔记 - 18.C编程预备计算机专业知识 - 什么是变量
c语言·开发语言·笔记·学习
好奇龙猫2 小时前
[大学院-python-base gammer learning2: python base programming ]
开发语言·python