算法8 查找算法 二分查找算法 BinarySeach

基于有序数组的二分查找:

        算法思想:

                取中间的索引,用目标索引 和 中间索引上的元素 进行比较。如果中间索引和我们查找的值相同,返回该索引。如果被查找的目标元素小于中间索引元素,我们就从左子数组上查找,否则从右子数组上查找。

        二分查找法的思路在1946年提出,大家觉得它是一个很简单的算法,然而从思想提出到第一个没有bug的代码实现,整个世界花了16年。你对此算法的态度是什么?

        算法实现(迭代版本):

package com.cosyit.offer.algorithms.find;


import java.util.Objects;

public class BinarySearch {

    /**
     * 二分查找法,在有序数组a中,查找target。
     *  此代码的要求:给你一张纸张+有限的思维训练 在纸上面就可以写出来。
     * @param a 数组
     * @param target 查找元素
     * @return 返回所在的元素索引index
     */
    public static int binarySearch(Comparable[] a,  Comparable target) {
        //在 已经排好序的 a[l,r] 中查找 target.
        int l = 0, r = a.length - 1;
        while (l <= r) {
//            int mid = (l + r) / 2; //中间元素mid.  // 这个地方,2个大int 相加会溢出,有这个bug.
            int mid = l + (r - l) / 2; // 这样就没bug了。
            int compare = target.compareTo(a[mid]);
            if (compare == 0) return mid;
            if (compare < 0)
                r = mid - 1; // mid -1 ? 因为上一个if 中我们已经判断了相等的情况,能执行到此处,肯定是不相等的。那么只能在 l...mid-1 这个范围中查找。
            else
                l = mid + 1;// 为什么+1,原因同上。
        }
        return -1;         //没找到return -1 .
    }

    public static void main(String[] args) {
        Integer [] a = {1,2,3,4,5,7,9,22,33,44,55,81};
        Integer target = 33;
        int index = binarySearch(a, target);
        System.out.println(index);
        System.out.println(Objects.equals(a[index], target));
    }
}

递归版本的实现:

package com.cosyit.offer.algorithms.find;

/**
 * 二分查找递归方式。
 * @author wangdawei
 */
public class BinarySearch {
     
    /**
     * @param key 查找对象 --->字
     * @param a   查找的数组--->字典
     * @return 数组中的位置--->在哪里
     */
    public static int binarySearch(int key, int[] a) {
        return __binarySearch(key, a, 0, a.length - 1);
    }


    /**
     * 33 -> 1 -  50  - 100
     * 找到33所在的位置。
     */

    public static int __binarySearch(int target, int[] a, int lo, int hi) {
        if (lo > hi) {
            return -1;
        }
          
        //防止 大int相加而产生的bug问题。
        int mid = lo + (hi - lo) / 2;

        //比较中间索引上的值。
        if (target < a[mid]) {
            return __binarySearch(target, a, lo, mid - 1);
        } else if (target > a[mid]) {
            return __binarySearch(target, a, mid + 1, hi);
        } else {
            //只有当查找元素=a[mid]
            return mid;
        }
    }

     public static void main(String[] args) {

          int[] arr = new int[10_0000];

          for (int i = 0; i < arr.length; i++) {
               arr[i] = i + 1;
          }
          System.out.println(binarySearch(55555, arr));
     }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值