经典算法9——索引查找

​索引查找是在索引表和主表(即线性表的索引存储结构)上进行的查找。

活动地址:CSDN21天学习挑战赛

索引查找的过程:

首先根据给定的索引值k1,在索引表上查找出索引值等于k1的索引项,以确定k1对应的子表在主表中的开始位置和长度,然后再根据给定的关键字k2,在对应的子表中查找出关键字等于k2的元素(结点)。

对索引表或子表进行查找时,若表是顺序存储的有序表,则既可以进行顺序查找,也可以进行二分查找,否则只能进行顺序查找。

设数组a是具有mainList类型的一个主表,数组b是具有indexList类型的在主表a上建立的一个索引表,m为索引表b的实际长度,即所含的索引项的个数,k1和k2分别为给定待查找的索引值和关键字,当然他们的类型分别为索引表中索引值域的类型和主表中关键字域在索引存储中,不仅便于查找单个元素,而且更便于查找一个子表的全部元素。当需要对一个子表中的全部元素依次处理时,只要从索引表中查找出该子表的开始位置即可。由此开始位置依次取出该子表的每一个元素,所以整个查找过程的时间复杂度为O(1),若不是采用索引存储,二是采用顺序存储,即使把它组织成有序表而进行二分查找时,索引查找一个子表中所有元素与二分查找一个子表的所有元素相比还是快很多。

 

伪代码

left = 1
right = T.length
while left <= right
    mid = (left + right) / 2
    if T[mid].key >= key
        right = mid - 1
    else
        left = mid + 1
i = T[right + 1].low
while i <= T[right + 1].high and A[i] != k
    i++
if i <= T[right + 1].high
    return i
else
    return -1

Java实现:

 a[16] = {9,22,12,14,35,42,44,38,48,60,58,47,78,80,77,82}
 int key = 48

public class BlockSearch {

    public static void main(String[] args) {
        // 主数据表
        int[] a = {9,22,12,14,35,42,44,38,48,60,58,47,78,80,77,82};
        // 待查关键字
        int key = 48;
        // 分块后获得索引表
        BlockTable[] t = {
                new BlockTable(22,0,3),
                new BlockTable(44,4,7),
                new BlockTable(60,8,11),
                new BlockTable(82,12,15)
        };
        // 调用算法,并输出结果
        int result = search(a, t, key);
        System.out.println(result);
    }

    private static int search(int[] a,BlockTable[] t,int key){
        // 初始化变量
        int left = 0;
        int right = t.length - 1;
        // 以下为二分查找算法,用于确定待查元素所在块
        while (left <= right){
            // 取中间元素,以下写法防止数据量较大时发生溢出
            int mid = (right - left) / 2 + left;
            if (t[mid].key >= key){
                // 此处直接使用mid
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        // 元素所在块为:right + 1,取对应的左端点
        int i = t[right + 1].low;
        // 使用顺序来扫描整个块
        while (i <= t[right + 1].high && a[i] != key){
            i++;
        }
        // 如果i没有超出块的范围,说明找到
        if (i <= t[right + 1].high){
            // 返回对应的逻辑位置
            return i + 1;
        }else {
            // 未找到时返回-1
            return -1;
        }
    }

}

class BlockTable{

    public BlockTable(int key, int low, int high) {
        this.key = key;
        this.low = low;
        this.high = high;
    }

    int key;
    int low;
    int high;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值