美文网首页
分块查找算法

分块查找算法

作者: 星邪Ara | 来源:发表于2022-03-25 10:43 被阅读0次

    分块查找又称索引顺序查找,它是顺序查找的一种改进方法。

    算法流程:

    • 先选取各块中的最大关键字构成一个索引表
    • 查找分两个部分:先对索引表进行二分查找顺序查找,以确定待查记录哪一块中;然后,在已确定的块中用顺序法进行查找。

    :算法的思想是将n个数据元素"按块有序"划分为m块(m ≤ n)。每一块中的结点不必有序,但块与块之间必须"按块有序",每个块内的的最大元素小于下一块所有元素的任意一个值

    所以,给定一个待查找的key,在查找这个key值位置时,会先去索引表中利用顺序查找或者二分查找来找出这个key所在块的索引开始位置,然后再根据所在块的索引开始位置开始查找这个key所在的具体位置。

    下面给出一段分块查找的代码,其思想和上面描述的一样,都是通过索引表来找key的位置。

    先给出主表和索引表:

    // 主表,size=30
        static int[] mainList = new int[]{
                101, 102, 103, 104, 105, 0, 0, 0, 0, 0,
                201, 202, 203, 204, 0, 0, 0, 0, 0, 0,
                301, 302, 303, 0, 0, 0, 0, 0, 0, 0
        };
    
        // 索引表
        static IndexItem[] indexItemList = new IndexItem[]{
                new IndexItem(1, 0, 5),
                new IndexItem(2, 10, 4),
                new IndexItem(3, 20, 3)
        };
    

    索引表类:

    static class IndexItem {
            public int index; //值比较的索引
            public int start; //开始位置
            public int length;//块元素长度(非空)
    
            public IndexItem(int index, int start, int length) {
                this.index = index;
                this.start = start;
                this.length = length;
            }
    
            //... getter and setter
        }
    

    索引查找算法:

    public static int indexSearch(int key) {
            IndexItem indexItem = null;
    
            //建立索引规则
            int index = key / 100;
    
            //遍历索引表
            for(int i = 0;i < indexItemList.length; i++) {
                //找到索引项
                if(indexItemList[i].index == index) {
                    indexItem = indexItemList[i];
                    break;
                }
            }
    
            //索引表中不存在该索引项
            if(indexItem == null)
                return -1;
    
            //根据索引项,在主表中查找
            for(int i = indexItem.start; i < indexItem.start + indexItem.length; i++) {
                if(mainList[i] == key)
                    return i;
            }
    
            return -1;
        }
    

    时间复杂度分析:先按二分查找去找key在索引表为大概位置(所给出代码是顺序查找),然后在主表中的可能所在块的位置开始按顺序查找,所以时间复杂度为O(log₂(m)+N/m),m为分块的数量,N为主表元素的数量,N/m 就是每块内元素的数量。

    分块查找的插入算法:

    /**
         * 插入数据
         *
         * @param key 要插入的值
         * @return true表示插入成功,false表示插入失败
         */
        public static boolean insert(int key) {
            IndexItem item = null;
    
            // 建立索引规则
            int index = key / 100;
            int i = 0;
            // 遍历索引表,找到对应的索引项
            for (i = 0; i < indexItemList.length; i++) {
                if (indexItemList[i].index == index) {
                    item = indexItemList[i];
                    break;
                }
            }
            // 索引表中不存在该索引项
            if (item == null) {
                return false;
            }
    
            // 根据索引项将值插入到主表中
            mainList[item.start + item.length] = key;
            // 更新索引表
            indexItemList[i].length++;
    
            return true;
        }
    

    打印主表的函数:

    /**
         * 遍历打印
         */
        public static void display(int[] list) {
            System.out.println("******** 展示开始 ********");
            if (list != null && list.length > 0) {
                for (int i = 0; i < list.length; i++) {
                    System.out.print(list[i] + " ");
                    if ((i + 1) % 10 == 0) {
                        System.out.println("");
                    }
                }
            }
            System.out.println("******** 展示结束 ********");
        }
    

    测试代码:

    public static void main(String[] args) {
            System.out.println("******** 索引查找 ********");
            System.out.println("");
            System.out.println("原始数据:");
            display(mainList);
            System.out.println("");
    
            //分块查找
            int key = 203;
            System.out.println("元素" + key + "列表中的位置为:" + indexSearch(key) + "\n");
    
            //按规则插入数据并查找
            int value = 106;
            System.out.println("插入数据:" + value);
    
            // 插入成功,查找插入位置
            if (insert(value)) {
                System.out.println("插入后的主表:");
                display(mainList);
                System.out.println("");
    
                System.out.println("元素" + value + "在列表中的位置为:" + indexSearch(value));
            }
        }
    

    原文:分块查找 - 賣贾笔的小男孩 - 博客园 (cnblogs.com)

    相关文章

      网友评论

          本文标题:分块查找算法

          本文链接:https://www.haomeiwen.com/subject/kdnkjrtx.html