JAVA数组二分查找

本文介绍了二分查找的基本原理及JAVA代码实现,强调了在使用二分查找前需对数组进行排序的重要性。

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

JAVA数组二分查找

前言

二分查找是一种比较高效的查找方式,使用此查找方式需要先将数组进行排序,如果数组未经排序效率就会很低,所以数组是必须要经过排序的

查找原理

Created with Raphaël 2.2.0 排序后数组 计算数组中间值 判断数组中间值是否 等于我们要查找的元素 是我们查找的元素返回当前middle下标 结束 判断当前中间下标是否已经为0 返回-1代表未找到此元素 判断当前中间元素是否 大于我们要查找的元素 如果不大于那说明我们 要找的元素在中间值 的右边(数组从小到大排序), 那么递归将之前的数组的start 换为中间值。 如果不大于那说明我们 要找的元素在中间值 的左边(数组从小到大排序), 那么递归将之前的数组的end 换为中间值。 yes no yes no yes no

代码实现

@Test
    public void test1() {
        Integer[] arr = new Integer[]{4, 3, 2, 1, 5, 10, 1, 11, 1, 1, 2, 123, 42142, 1};
        arr = mergeSort(arr, Comparator.naturalOrder()); //使用二分法需要先将数组排序 (归并排序)

        for (Integer integer : arr) {
            System.out.println(integer);
        }

        System.out.println(binarySearch(arr, 42142, 0, arr.length, Comparator.naturalOrder()));
    }

    /**
     * 使用二分法查找元素,如果有多个仅仅只返回其中一个数组下标(乱序)。
     *
     * @param arr 目标数组
     * @param find 查找元素
     * @param start 数组开始下标
     * @param end 数组结束下标
     * @param comparator 元素比较规则
     * @return 查找的元素在目标数组的下标
     */
    private int binarySearch(Object[] arr, Object find, int start, int end, Comparator comparator) {
        if (arr == null) throw new NullPointerException("arr can not be empty!");

        int middle = (end - start) / 2 + start;

        int result = comparator.compare(arr[middle],find);

        if(middle == 0 && result != 0) return -1;

        if(result > 0) {
            return binarySearch(arr, find, start, middle, comparator);
        } else if(result < 0) {
            return binarySearch(arr, find, middle, end, comparator);
        } else {
            return middle;
        }
    }

    /**
     * 归并排序
     *
     * @param arr 排序数组
     * @param comparator 比较规则
     * @return 排序后的数组
     */
    private <T> T[] mergeSort(T[] arr, Comparator<T> comparator) {
        T[] cache = arr.clone();
        int step = 2;

        while (step <= arr.length * 2) {
            int c = 0;
            for (int i = 0; i < arr.length; i += step) {
                int l = i, r = l + (step >> 1) > arr.length ? arr.length : i + (step >> 1);
                int lm = r;
                int rm = i + step > arr.length ? arr.length : i + step;

                while (l < lm && r < rm) {
                    if (comparator.compare(arr[l],arr[r]) > 0) {
                        cache[c] = arr[r];
                        r++;
                        c++;
                    } else {
                        cache[c] = arr[l];
                        l++;
                        c++;
                    }
                }
                while (l < lm) {
                    cache[c] = arr[l];
                    l++;
                    c++;
                }
                while (r < rm) {
                    cache[c] = arr[r];
                    r++;
                    c++;
                }
                System.arraycopy(cache, 0, arr, 0, cache.length);
            }
            step = step << 1;
        }

        return (T[]) cache;
    }

归并排序可以参考 > 归并排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值