Java中的查找算法-分块查找的学习分享

分块查找算法适用情境:

有些数据并不是按一定顺序排列的,也不是完全没有顺序的,而是在无序中透露出有序,例如下面的数据

710131916202722304036435048

可以把这些数据按照下面的方式进行分块 

71013
191620
2722304036
435048

 遵循的原则:

1.前一块中的最大数据,小于后一块中的所有数据(块内无序,块间有序)

2.块数数量一般等于数据的个数开根号。例如16个数据一般分为4块左右

这就是分块查找的核心思路:先确定要查找的元素在哪一块,然后在块内一个个查找

代码实现思路:

(1)先存储四块数据的信息对每一块都创建对象,具体是通过创建数组blockArr存放每一个块对象的信息

(2)查找blockArr确定要查找的数据属于哪一块

(3)在块中单独遍历这一数据

代码实现:

int[] arr = {17,5,9,12,23,19,32,24,37,27,45,36,50,49,61,57,72,66};

 例如我们要查询元素number是否在数组arr中,先对其进行分块,要遵循分块的原则,初步使其分成下面四块

int[] arr = {17,5,9,12,
             23,19,
             32,24,37,27,45,36,
             50,49,61,57,72,66};

数据不是很均匀,为了使其更加均匀在保证分块原则的前提下考虑分成三块

int[] arr = {17,5,9,12,23,19,
             32,24,37,27,45,36,
             50,49,61,57,72,66};

用下面的类来描述这个块

class Block {
    private int max; //块中的最大值
    private int startIndex;  //起始索引
    private int endIndex;    //结束索引
}

 将其补充为JavaBean类,然后创建三个块的对象

Block b1 = new Block(23,0,5);
Block b2 = new Block(45,6,11);
Block b3 = new Block(72,12,17);
//管理三个块的对象(索引表)
Block[] blockArr = {b1,b2,b3};
//记录要查找的元素
int number = 36;

首先确定number在哪一个块中,定义方法得到在索引表中的索引

public static int findIndexBlock(Block[] blockArr,int number){
    //从0索引开始遍历blockArr,如果nubmer小于max,那么number就在这个块中
    for (int i = 0; i < blockArr.length; i++) {
        if(number <= blockArr[i].getMax()){
            return i;
        }
    }
    return -1;
}

通过上个方法再利用分块查找的原理,查询number的索引

private static int getIndex(Block[] blockArr, int[] arr, int number) {
        // 1.确定number是在哪一个块中
        int indexBlock = findIndexBlock(blockArr,number);

        if(indexBlock == -1){
            //表示number不在块中
            return -1;
        }

        // 2.获取这一块的起始索引和结束索引
        int startIndex = blockArr[indexBlock].getStartIndex();
        int endIndex = blockArr[indexBlock].getEndIndex();

        // 3.遍历
        for (int i = startIndex; i <= endIndex ; i++) {
            if(arr[i] == number){
                return i;
            }
        }
        //表示number不在数组中
        return -1;
    }

正式查找中,调用方法,传递索引表,数组以及要查找的元素,最后打印得出索引值,没有找到则返回-1

int index = getIndex(blockArr,arr,number);
System.out.println(index);

完整代码:

public class divideBlock {
    public static void main(String[] args) {
        
        int[] arr = {17,5,9,12,23,19,
                     32,24,37,27,45,36,
                     50,49,61,57,72,66};
        //创建三个块的对象
        Block b1 = new Block(23,0,5);
        Block b2 = new Block(45,6,11);
        Block b3 = new Block(72,12,17);
        //管理三个块的对象(索引表)
        Block[] blockArr = {b1,b2,b3};

        //记录要查找的元素
        int number = 36;

        //调用方法,传递索引表,数组以及要查找的元素
        int index = getIndex(blockArr,arr,number);

        //打印
        System.out.println(index);
    }

    //分块查找的原理,查询number的索引
    private static int getIndex(Block[] blockArr, int[] arr, int number) {
        // 1.确定number是在哪一个块中
        int indexBlock = findIndexBlock(blockArr,number);

        if(indexBlock == -1){
            //表示number不在数组中
            return -1;
        }

        // 2.获取这一块的起始索引和结束索引
        int startIndex = blockArr[indexBlock].getStartIndex();
        int endIndex = blockArr[indexBlock].getEndIndex();

        // 3.遍历
        for (int i = startIndex; i <= endIndex ; i++) {
            if(arr[i] == number){
                return i;
            }
        }
        return -1;
    }

    //确定number在哪一个块中
    public static int findIndexBlock(Block[] blockArr,int number){
        //从0索引开始遍历blockArr,如果nubmer小于max,那么number就在这个块中
        for (int i = 0; i < blockArr.length; i++) {
            if(number <= blockArr[i].getMax()){
                return i;
            }
        }
        return -1;
    }
}

class Block {
    private int max; //最大值
    private int startIndex;  //起始索引
    private int endIndex;    //结束索引

    public Block() {
    }

    public Block(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;
    }

    public String toString() {
        return "Block{max = " + max + ", startIndex = " + startIndex + ", endIndex = " + endIndex + "}";
    }
}

最后要查找的元素为36,运行后得到在数组中的索引-------11

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值