二分查找 (Java) 以及 二分查找函数运用

本文详细介绍了Java中的二分查找算法,包括基本二分查找方法(适用于无重复元素数组)和处理有重复元素情况的方法,以及如何使用Comparator自定义比较规则。
摘要由CSDN通过智能技术生成

思路:

前提:被查找数组是有序的

  1. 确定要查找的数组范围,通常用两个指针leftright表示,初始时left指向第一个元素,right指向最后一个元素。
  2. 计算数组的中间位置mid,可以使用(left + right) / 2来得到。
  3. 将目标值与中间位置的元素进行比较:
    • 如果目标值等于中间位置的元素,则找到了目标值,返回中间位置。
    • 如果目标值小于中间位置的元素,则说明目标值在左半部分,更新rightmid - 1,继续执行步骤2。
    • 如果目标值大于中间位置的元素,则说明目标值在右半部分,更新leftmid + 1,继续执行步骤2。
  4. 重复执行步骤2和步骤3,直到找到目标值或者left大于right,表示未找到目标值。

 代码实现

 /**
     * @param arr   查找的数组
     * @param left  左边的索引
     * @param right 右边的索引
     * @param value 查找的值
     * @return 返回下标,没有返回-1
     */

    public static int binarySearch(int[] arr, int left, int right, int value) {
        if (left > right)
            return -1;
        int mid = (left + right) / 2;
        int midVal = arr[mid];
        if (value > midVal) {
            //向右递归
            return binarySearch(arr, mid + 1, right, value);
        } else if (value < midVal) {
            //向左递归
            return binarySearch(arr, left, mid - 1, value);
        } else
            return mid;
    }

当被查找数组里面有重复元素时

 public static ArrayList<Integer> binarySearch(int[] arr, int left, int right, int value) {
        if (left > right) {
            return new ArrayList<Integer>();
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];
        if (value > midVal) {
            //向右递归
            return binarySearch(arr, mid + 1, right, value);
        } else if (value < midVal) {
            //向左递归
            return binarySearch(arr, left, mid - 1, value);
        } else {
            ArrayList<Integer> resIndexList = new ArrayList<>();
            int temp = mid - 1;
            while (true) {
                if (temp < 0 || arr[temp] != value) {
                    break;
                }
                resIndexList.add(temp);
                temp--;
            }
            resIndexList.add(mid);
            temp = mid + 1;
            while (true) {
                if (temp > arr.length - 1 || arr[temp] != value) {
                    break;
                }
                resIndexList.add(temp);
                temp++;
            }
            return resIndexList;
        }

    }

binarySearch方法

binarySearch方法为二分法查找,是Arrays包里面的

 1.binarySearch(Object[], Object key)

方法的object[]参数是要查找的数组,key参数为要查找的key值。

这个函数返回目标元素在数组中的索引,如果找到了目标元素。如果未找到目标元素,则返回一个负数,表示该元素在数组中的插入点位置的相反数减1

2.binarySearch(Object[], int fromIndex, int toIndex, Object key)

方法的object[]参数为要查找的数组,fromindex参数为开始索引(包括),toindex为结束索引(不包括),两个参数之间为查找的范围。key为要查找的key。

例子

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5, 6};
        int key = 4;
        int index = Arrays.binarySearch(array, key);
        
        if (index >= 0) {
            System.out.println("找到了目标元素,索引为:" + index);
        } else {
            System.out.println("未找到目标元素,应插入的位置为:" + (-index - 1));
        }
    }
}

3.public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)

  • T[] a 表示要进行二分查找的数组。
  • T key 表示要查找的目标元素。
  • Comparator<? super T> c 是一个比较器对象,用于指定元素之间的比较规则。

使用这个重载版本的方法,我们需要提供一个实现了Comparator接口的比较器对象c,并在其中实现compare方法来定义元素之间的比较规则。然后将这个比较器对象传递给binarySearch方法,这样就可以在自定义的比较规则下执行二分查找

例子:

import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        String[] array = {"apple", "banana", "orange", "pear", "grape"};
        String key = "orange";
        
        // 自定义比较器,按照字符串长度进行比较
        Comparator<String> lengthComparator = new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s1.length() - s2.length();
            }
        };
        
        // 使用自定义比较器进行二分查找
        int index = Arrays.binarySearch(array, key, lengthComparator);
        
        if (index >= 0) {
            System.out.println("找到了目标元素,索引为:" + index);
        } else {
            System.out.println("未找到目标元素,应插入的位置为:" + (-index - 1));
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值