1、基本概念

索引查找又称分级查找。

索引存储的基本思想是:首先把一个集合或线性表(他们对应为主表)按照一定的函数关系或条件划分成若干个逻辑上的子表,为每个子表分别建立一个索引项,由所有

这些索引项构成主表的一个索引表,然后,可采用顺序或链接的方式来存储索引表和每个子表。

索引表的类型可定义如下:

struct IndexItem
{
    IndexKeyType index;//IndexKeyType为事先定义的索引值类型
    int start;         //子表中第一个元素所在的下标位置
    int length;        //子表的长度域
};
typedef struct IndexItem indexlist[ILMSize];//ILMSize为事先定义的整型常量,大于等于索引项数m

主表的类型可定义如下:

typedef struct ElemType mainlist[MaxSize];//MaxSize为事先定义的整型常量,大于等于主表中元素的个数n

在索引表中的每个索引项对应多条记录,则称为稀疏索引,若每个索引项唯一对应一条记录,则称为稠密索引。

2、索引查找算法

过程:

首先根据给定的索引值K1,在索引表上查找出索引值等于K1的索引项,以确定对应子表在主表中的开始位置和长度,然后再根据给定的关键字K2,在对应的子表中查找出

关键字等于K2的元素。

设数组A是具有mainlist类型的一个主表,数组B是具有indexlist类型的在主表A上建立的一个索引表,m为索引表B的实际长度,即所含的索引项的个数,K1和K2分别为给定

带查找的索引值和关键字,并假定每个子表采用顺序存储,则索引查找算法为:

int Indsch(mainlist A, indexlist B, int m, IndexKeyType K1, KeyType K2)
{//利用主表A和大小为 m 的索引表B索引查找索引值为K1,关键字为K2的记录
//返回该记录在主表中的下标位置,若查找失败则返回-1
int i, j;
for (i = 0; i < m; i++)
if (K1 == B[i].index)
break;
if (i == m)
return -1; //查找失败
j = B[i].start;
while (j < B[i].start + B[i].length)
{
if (K2 == A[j].key)
break;
else
j++;
}
if (j < B[i].start + B[i].length)
return j; //查找成功
else
return -1; //查找失败
}
若 IndexKeyType 被定义为字符串类型,则算法中相应的条件改为 strcmp (K1, B[i].index) == 0; 同理,若KeyType 被定义为字符串类型
则算法中相应的条件也应该改为 strcmp (K2, A[j].key) == 0 若每个子表在主表A中采用的是链接存储,则只要把上面算法中的while循环
和其后的if语句进行如下修改即可: while (j != -1)//用-1作为空指针标记
{
if (K2 == A[j].key)
break;
else
j = A[j].next;
}
return j;

若索引表B为稠密索引,则更为简单,只需查找索引表B,成功时直接返回B[i].start即可。

索引查找分析:

索引查找的比较次数等于算法中查找索引表的比较次数和查找相应子表的比较次数之和,假定索引表的长度为m,子表长度为s,

则索引查找的平均查找长度为:

ASL= (1+m)/2 + (1+s)/2 = 1 + (m+s)/2

假定每个子表具有相同的长度,即s=n/m, 则 ASL = 1 + (m + n/m)/2 ,当m = n/m ,(即m = √▔n,此时s也等于√▔n),  ASL = 1 + √▔n  最小 ,时间复杂度为 O(√▔n)

可见,索引查找的速度快于顺序查找,但低于二分查找。

在索引存储中,不仅便于查找单个元素,而且更方便查找一个子表中的全部元素,若在主表中的每个子表后都预留有空闲位置,则索引存储也便于进行插入和删除运算。

3、分块查找

分块查找属于索引查找,其对应的索引表为稀疏索引,具体地说,分块查找要求主表中每个子表(又称为块)之间是递增(或递减)有序的。即前块中最大关键字必须

小于后块中的最小关键字,但块内元素的排列可无序。它还要求索引值域为每块中的最大关键字。

下图是用于分块查找的主表和索引表的示例:

分块查找的算法同上面的索引查找算法类似,具体如下:

int Blocksch(mainlist A, indexlist B, int m, KeyType K)
{//利用主表A和大小为m的索引表B分块查找关键字为K的记录
int i, j;
for (i = 0; i < m; i++)
if (K <= B[i].index)
break;
if (i == m)
return -1; //查找失败
j = B[i].start;
while (j < B[i].start + B[i].length)
{
if (K == A[j].key)
break;
else
j++;
}
if (j < B[i].start + B[i].length)
return j;
else
return -1;
} 若在索引表上不是顺序查找,而是二分查找相应的索引项,则需要把算法中的for循环
语句更换为如下的程序段: int low = 0, high = m - 1;
while (low <= high)
{
int mid = (low + high) / 2;
if (K == B[mid].index)
{
i = mid;
break;
}
else if (K < B[mid].index)
high = mid - 1;
else
low = mid + 1;
}
if (low > high)
i = low; 这里当二分查找失败时,应把low的值赋给i,此时b[i].index是刚大于K的索引值
当然若low的值为m,则表示真正的查找失败。

索引查找(索引查找、分块查找) C语言实现的更多相关文章

  1. C语言两种查找方式(分块查找,二分法)

    二分法(必须要保证数据是有序排列的):   分块查找(数据有如下特点:块间有序,块内无序):    

  2. c语言完成分块查找

    首先要把一系列数组均匀分成若干块(最后一个可以不均匀) 每块中元素任意排列,即块中数字无序,但是整个块之间要有序.因此也存在局限性. #include<stdio.h> //分块查找法 v ...

  3. 查找->静态查找表->分块查找(索引顺序表)

    文字描述 分块查找又称为索引顺序查找,是顺序查找的一种改进方法.在此查找算法中,除表本身外, 还需要建立一个”索引表”.索引表中包括两项内容:关键字项(其值为该字表内的最大关键字)和指针项(指示该子表 ...

  4. HDOJ1251(前缀匹配---分块查找&map应用)

    分块查找算法 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm ...

  5. 分块查找(Blocking Search)

    1.定义 分块查找(Blocking Search)又称索引顺序查找.它是一种性能介于顺序查找和二分查找之间的查找方法. 2.基本思想 分块查找的基本思想是: (1)首先查找索引表 索引表是有序表,可 ...

  6. 数据结构之二分查找——Java语言实现

    场景描述:给出一个数据序列长度为N,然后查找 一个数是否在数据序列中,若是,则返回在序列中的第几个位置. 首先可能第一个想到的就是按照顺序,从前到后一个一个进行查找,直到找到为止,若最后都没有,则说明 ...

  7. 折半查找(C语言)

    一.二分查找 在C和C++里,二分查找是针对有序数组所用的一种快速查找元素的方法. 二.二分查找的条件以及优缺点 条件:针对有序数组(元素从小到大或从大到小) 优点:查询速度较快,时间复杂度为O(n) ...

  8. 顺序查找&二分查找&索引查找

    1.查找技术的分类.如下图: 2.什么是顺序查找呢?(无序表) 顺序查找的原理很简单,就是遍历整个列表,逐个进行记录的关键字与给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录.如 ...

  9. JS-七大查找算法

    顺序查找 二分查找 插值查找 斐波那契查找 树表查找 分块查找 哈希查找 查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录).查找算法分类:1)静态查找和动态查找:注 ...

随机推荐

  1. 找不好重现的bug的一个小技巧————守株待兔

    最近碰到一个问题就是数据库中偶尔出现一条没有id的数据,可恨的是怎么也找不到重现这个问题的原因,只好换种方式来找了,那么就是我标题所说的守株待兔方法. 因为我发现出现bug的数据库里面的数据有个字段为 ...

  2. String,StringBuffer,StringBuilder的简单比较

    原文:http://blog.csdn.net/rmn190/article/details/1492013   String 字符串常量StringBuffer 字符串变量(线程安全)StringB ...

  3. 『重构--改善既有代码的设计』读书笔记----Change Reference to Value

    如果你有一个引用对象,很小且不可改变,而且不易管理,你就需要考虑将他改为一个值对象.在Change Value to Reference我们说过,要在引用对象和值对象之间做选择,有时候并不容易,有了重 ...

  4. Zend Studio 11.0.2 破解和汉化

    本方法适用于Zend Studio 11.0.2,亲测,其他版本未知. 破解方法:覆盖安装目录 plugins 里同名文件,启动任意输入即可注册. Windows版下载地址:http://downlo ...

  5. Struts面试笔记

    Struts2面试题1.struts2工作流程Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher.业务控制器Action和用户实现的企业业务逻辑组件. 核心控制器 ...

  6. 百度劫持js代码

    js代码为: var myDate=new Date(); //返回一日期对象,可以调用getDate(),内容为当前时间,这句是新建一个对象d建好对象后d就有函数date()中的所有特性 var h ...

  7. [转]hive中order by,distribute by,sort by,cluster by

    转至http://my.oschina.net/repine/blog/296562 order by,distribute by,sort by,cluster by  查询使用说明 1 2 3 4 ...

  8. 区分html与css中的属性

    CSS中id与Class的区别 1.在CSS文件里书写时,ID加前缀"#":CLASS用"." 2.id一个页面只可以使用一次:class可以多次引用. 3.I ...

  9. 【Java】servlet和servlet 容器

    servlet不是线程安全的,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,所以你的项目中如果只有一个servlet,那么web容器就只会创建一个实例 ...

  10. 全球顶级专家为你解读:什么是真正的 DevOps?

    [编者按]本文是 Skytap 内容主编 Noel Wurst 对 DevOps Enterprise Summit (DOES)的不完全综述,内容包括了 Noel 和一些与会嘉宾的思考,旨在勾画 D ...