java-查找算法

基本查找/顺序查找

这个无需怎么介绍,简而言之就是,对数据进行遍历,然后找到对应的要查找数据

二分查找

前提要求:数据必须是2有序的

思路:每次就是对半查找,如下图简要的概述

举例:一组数据为7,23,79,81,103,127,131,147,现在我们要查找数据127

代码如下

package aaa;
import java.util.Scanner;
public class suan_fa {
    public static void main(String[] args) {
        int []arr={7,23,79,81,103,127,131,147};
        Scanner sc=new Scanner(System.in);
        int num= sc.nextInt();
        System.out.println(find(arr,num));
    }
    public static int find(int []arr,int num){
        int min=0;
        int max=arr.length-1;
        while(true){
            if(min>max){
                return -1;
            }
            int mid=(min+max)/2;
            if(num>arr[mid]){
                min=mid+1;
            }
            else if(num<arr[mid])
            {
                max=mid-1;
            }
            else {
                return mid;
            }

        }
    }
}

加上注释的代码如下图

插值查找(了解即可)

把上面二分查找的mid的计算公式替换掉就行

要求:数据分布要尽可能均匀

斐波那契查找(了解即可)

分块查找

分块查找的核心:块内无序,块外有序

如何理解?

举一个例子

如图中一串数据分成了4大块,可以看到这4大块,每一块里面的顺序是无序的,但是块2的最小值一定大于块1的最大值,所以块外是有序的

到底如何书写这个代码,我们以下面的例子为例:

一段数据为16,5,9,12,21,18,32,23,37,26,45,34,50,48,61,52,73,66

目的:查找50所在的索引

我们到底要分多少块呢?

一般情况:块数=数据个数开根号,但是这不是绝对的

如这个题目按理说要分为4板块,但是为了每个板块内的数据个数都差不多,最后选择分为3大块

16,5,9,12,21,18

32,23,37,26,45,34

50,48,61,52,73,66

代码实现如下

package aaa;
import java.util.Scanner;
public class bbb {
    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};
        block b1=new block(21,0,5);
        block b2=new block(45,6,11);
        block b3=new block(73,12,17);
        block []blockArr={b1,b2,b3};
        Scanner sc=new Scanner(System.in);
        int num=sc.nextInt();
        System.out.println(getIndex(blockArr,arr,num));

    }
    public static int getIndex(block []blockArr,int []arr,int num){
        int indexBlock=findIndex(blockArr,num);
        if(indexBlock==-1)
            return -1;
        int startIndex=blockArr[indexBlock].getStart();
        int endIndex=blockArr[indexBlock].getEnd();

        for (int i = startIndex; i < endIndex; i++) {
            if(arr[i]==num){
                return i;
            }
        }
        return -1;
    }
    public static int findIndex(block[]blockArr,int num){
        for(int i=0;i<blockArr.length;i++){
            if(num<blockArr[i].getMax()){
                return i;
            }

        }
        return -1;
    }
}
class block{
    private int max;
    private int start;
    private int end;
    public block(){

    };
    public block(int max,int start,int end){
        this.max=max;
        this.start=start;
        this.end=end;
    }

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

    public void setStart(int start) {
        this.start = start;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    public int getStart() {
        return start;
    }

    public int getEnd() {
        return end;
    }

    public int getMax() {
        return max;
    }
}

带有注释的代码如下图

分块查找的扩展:

如果给定的数据不是有规律的怎么办?如下图

只需在块类里面加上一个min的成员变量就行,这是为了确定好数据在哪个块,剩下的就和上面的一样了

哈希查找(感兴趣可以了解)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值