详解:java 查找算法 -- 基本查找( 顺序查找 ) 二分查找 分块查找

基本查找( 顺序查找 )

举个例子 基本查找( 顺序查找 )

从零开始以此往后查找,查找到就返回当前索引,并结束查找

    public static void main(String[] args) {
        // 定义这个数组
        int[] arr = {131,127,147,81,103,23,7,79,81};
        // 查找81
        int number = 81;
        // 调用函数 进行查找  arr 是数组  number 要查找的数字
        ArrayList<Integer> list = BaseSearch(arr, number);
        // 打印这个集合。因为查找到的数组不只是一个,,集合里存放查找元素所在的索引
        System.out.println(list);

    }

    private static ArrayList<Integer> BaseSearch(int[] arr, int number) {
        ArrayList<Integer> list = new ArrayList<>();
        // 循环遍历
        for (int i = 0; i < arr.length; i++) {
            // 如果数值与要查找的number 数值一样就把所在的索引加入到集合
            if(arr[i] == number){
                list.add(i);
            }
        }
        // 返回集合
        return list;
    }

二分查找

前提条件:数组中的数据必须是有序的
核心逻辑:每次排掉数组一半的范围
min 和 max 表示当前查找的范围
mid 表示 当前元素的索引
如果 mid索引的元素 大于查找的元素 缩小范围,max = mid - 1
如果 mid索引的元素 小于查找的元素 缩小范围,mix  = mid + 1

举个例子(二分查找)

    public static void main(String[] args) {
        // 定义这个数组
        int[] a = {10,22,38,46,59,62,75,83,91,100};
        // 查找91
        int num = BaseSearch(a, 91);
        //打印查找到的索引
        System.out.println(num);
    }

    private static int BaseSearch(int[] arr, int number) {
        // 定义开始 和 结束标签 的变量
        int max = arr.length - 1;
        int min = 0;
        while (true){
        // 这个已经放到循环里面,每次都要重新给mid 定位置  mid 就等于 当前范围的中间范围
            int mid = (max + min) / 2;// 中间值
            // 表示查询不到了
            if(min > max){
                return -1;
            }
            // 如果 mid索引的元素 大于查找的元素 缩小范围,max = mid - 1
            if(arr[mid] > number){
                max = mid - 1;
                // 如果 mid索引的元素 小于查找的元素 缩小范围,mix = mid + 1
            }else if(arr[mid] < number){  
                min = mid + 1;
                // 就找到了
            }else if(arr[mid] == number){
                return mid; // 结束循环
            }
        }

    }

改进:我想让mid 尽量偏向可能的值
在这里插入图片描述

    public static void main(String[] args) {
        // 定义这个数组
        int[] a = {10, 22, 38, 46, 59, 62, 75, 83, 91, 100};
        // 查找91
        int num = BaseSearch(a, 91);
        //打印查找到的索引
        System.out.println(num);
    }

    private static int BaseSearch(int[] arr, int number) {
        // 定义开始 和 结束标签 的变量
        int max = arr.length - 1;
        int min = 0;
        while (true) {
            // 改进
            //查找数值-数组中最小的数值
            //数组中最大数-数组中最小数
            double may_value = (double) (number - arr[min]) / (arr[max] - arr[min]);
            // 最小索引 - may_value * (最大索引-最小索引)
            int mid = (int) (min + may_value * (max - min));
            // 这个已经放到循环里面,每次都要重新给mid 定位置  mid 就等于 当前范围的中间范围
//            int mid = (max + min) / 2;   中间值
            // 表示查询不到了
            if (min > max) {
                return -1;
            }
            // 如果 mid索引的元素 大于查找的元素 缩小范围,max = mid - 1
            if (arr[mid] > number) {
                max = mid - 1;
                // 如果 mid索引的元素 小于查找的元素 缩小范围,mix = mid + 1
            } else if (arr[mid] < number) {
                min = mid + 1;
                // 就找到了
            } else if (arr[mid] == number) {
                return mid; // 结束循环
            }
        }

    }

分块查找

条件:
分块的个数 = 数组的长度开根号

块内无序,块间有序,第一块的最大值一定是比第二个块的最小值要小

举个例子(分块查找)

public class block {
    public static void main(String[] args) {
        //    创建数组
        int[] arr = {16,5,9,12,21,18,
                32,23,37,26,45,34,
                50,48,61,52,73,66
        };
        // 创建对象
        Pin p1 = new Pin(21,0,6);
        Pin p2 = new Pin(45,7, 12);
        Pin p3 = new Pin(73,13,18);
        // 把对象封装成数组
        Pin[] box = {p1,p2,p3};
        // 我们查找91
        // 调用函数
        int index = indexOf(box,arr,45);
        System.out.println(index);
    }

    private static int indexOf(Pin[] box, int[] arr, int number) {
        // 获得块索引
        int index = findIndex(box, number);
        // 检查是不是 -1
        if(index < 0){
            return -1;
        }
        // 因为已经获得准确位置勒,所以只需要遍历这个范围就可以勒
        for (int i = box[index].getStartIndex(); i < box[index].getEndIndex(); i++) {
            if(arr[i] == number){
                return i;
            }
        }
        return -1;
    }

    // 这个方法用来确定数值在那一块中
    private static int findIndex(Pin[] box, int number) {

        // 基本查找
        // 遍历这个对象
        for (int i = 0; i < box.length; i++) {
            // 查看块的最大值是不是大于等于这个数字
            if(box[i].getMax() >= number){
                // 返回当前索引
                return i;
            }
        }
        return -1;
    }

}
// 定义 类
class Pin{
    private int max; // 最大值
    private int startIndex; // 开始索引和结束索引
    private int endIndex;

    public Pin() {
    }

    public Pin(int max, int startIndex, int endIndex) {
        this.max = max;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值