算法-java

文章详细介绍了Java中三种不同版本的二分查找算法:左闭右闭、左闭右开以及改进版,并分析了它们的逻辑差异。同时,文章讨论了算法的时间复杂度,包括渐进上界、渐进下界和渐进紧界的概念,以及如何简化函数表达式来确定时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法-java

一、 二分查找

1. 二分-左闭右闭

public Integer erfen(int target,int arr[]){
    int i = 0;
    int j = arr.length-1;
    int m = 0;
    while(i<=j){
        m=(i+j)>>>1;
        if (target<arr[m]){        // 目标在中间数左侧,缩小右边界
            j=m-1;
        }else if (arr[m]<target){  // 目标在中间数右侧,缩小左边界
            i=m+1;
        }else {                    // 目标就是中间数
            return m;
        }
    }
    return -1;
}

注:

  1. 算法解释:用i和j代表序列的两边,通过不断取中间数缩小目标范围,只要i不在j右侧就一直进行。(i和j都参与比较,左闭右闭运算)
  2. i<=j 代表i和j指向的元素也会参与比较
  3. i<j 代表只有m参与比较
  4. java把二进制最高位看做符号位,因此,当两个足够大的数相加时,可能会最高位进一,导致得数为负数。
  5. ‘>>>1’ 无符号右移1位,最高位取0补位,因此,无符号右移1位替代除以2,可以避免最高位进一变负数的情况。
  6. 编程习惯:升序的数组,都用小于号。可以更清晰的看到数字的位置,如:
    target < arr[m],arr[m] < target

2. 二分-左闭右开

public Integer newErfen(int target,int arr[]){
    int i = 0;
    int j = arr.length;            // j取索引外的值
    int m = 0;
    while(i<j){                    // 只要i和j不相交就一直循环
        m=(i+j)>>>1;
        if (target<arr[m]){        
            j=m;                   // 直接j=m
        }else if (arr[m]<target){  
            i=m+1;
        }else {                    
            return m;
        }
    }
    return -1;
}

注:

  1. 左闭右开,i参与比较,j不再参与比较
  2. 因为j=m,若还while(i<=j),当查找一个不在数组的数时,最后i和j相等,即m=j=(i+j)>>>2,导致m一直不变,陷入死循环。

3. 二分-改进版

public Integer newErfen2(int target,int arr[]){
    int i = 0;
    int j = arr.length;           // j不可能指向目标
    while(1<(j-i)){               // 一直循环到区间范围只剩1才结束
        int m = (i+j)>>>1;
        if (target < arr[m]) {
            j = m;                // 缩小右边界
        }else {
            i = m;                // 缩小左边界
        }
    }
    if (arr[i] == target) {
        return i;
    }else{
        return -1;
    }
}

注:

  1. 左闭右开算法
  2. 循环只缩小查找范围,不找目标,在循环外比较a[i]与target值
  3. 循环内的比较次数比改进前少了
  4. 时间复杂度稳定为Θ(log₂n)

二、算法性能

1.时间复杂度

定义:一个算法的执行,随着数据规模增大,而增长的时间成本。不依赖于环境因素(软件因素和硬件因素)
设:
c,c1,c2都是一个常数
f(n)实际执行的代码行数与n的行数
g(n)是经过化简,变化趋势与f(n)一致的n的函数

1.1 渐进上界

从某个常数n开始,cg(n)总是位于f(n)上方,那么记作 O(g(n)),通常表示为该算法最差的运行情况
例如:

  1. 设f(n)=3n+3,g(n)=n 取c=4,在n=3之后,g(n)可以作为f(n)的渐进上界,因此表示法写作O(g(n))
  2. 设 f(n)=5 * floor(log₂n)+9, 则g(n)=log₂n, 即渐进上界O(log₂n)
  3. 已知f(n),求g(n):
    3.1 去除相加的常量,如2里面的+9
    3.2 去除相乘的常量,如2里面的5*
    3.3 去除低次项,如:f(n)=n³+n²,则n²可以去掉,因为n²增长规模远小于n³
1.2. 渐进下界

从某个常数n开始,cg(n)总是位于f(n)下方,那么记作 Ω(g(n)),通常表示为该算法最好的运行情况

1.3. 渐进紧界

从某个常数n开始,f(n)总是位于c1g(n)和c2g(n)之间,那么记作偶θ(g(n))

2. 空间复杂度

定义:一个算法执行随数据规模增大,而增长的额外空间成本,一般也用O表示
一般指该算法的所有变量共占了多少字节。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值