分块查找又称索引顺序查找,这是一种性能介于顺序查找和折半查找之间的一种查找方法。在此查找法中,出表本身以外,尚需建立一个“索引表”
例如,下图所示为一个表及索引表,表中有18个记录,可分为3个子表(R1,R2,.....R6),(R7,R8.....R12),(R13,R14......R18),对每个子表建立一个索引项,其中包括两项内容:关键字(其值为该子表中的最大关键字)和指针项(指示该子表的第一个记录在表中的位置)。索引表按关键字有序,则表或者有序或者分块有序。所谓“分块有序”指的是第二个子表中所有记录的关键字均大于第一个子表中的最大关键字,第三个子表中的所有关键字均大于第二个子表中的最大关键字,......,以此类推。
因此,分块查找的步骤为:先确定待查记录所在的子块,然后在块中顺序查找。由于由索引项组成的索引表按关键字有序,则确定块的查找可以用顺序查找,亦可用折半查找。而块中记录是任意排序的,则在块中只能是顺序查找。
代码实现如下:
#include <stdio.h> #include <stdlib.h> struct index{//定义索引表 int key;//最大关键字 int start;//起始地址 }newIndex[3]; //定义结构体数组 int cmp(const void*a,const void*b){ return (*(struct index*)a).key>(*(struct index*)b).key?1:-1; } int search(int key,int a[]) { int i=0,startvalue; while(i<3&&newIndex[i].key <key) { i++; } if(i>3) { return -1; } startvalue=newIndex[i].start ; while(startvalue<=startvalue+5&&a[startvalue]!=key) { startvalue++; } if(startvalue>startvalue+5) { return -1; } return startvalue; } int main() { int i,j=1,k,key,n; int a[20]; printf("要输入数据的个数为:\n"); scanf("%d",&n); printf("请输入(数量为3的整数倍的)数据:\n"); for(i=0;i<n;i++) { scanf("%d",&a[i]); } //确定模块的起始值和最大值 for(i=0;i<3;i++) { newIndex[i].start =j+1; j+=6; for(int k=newIndex[i].start;k<=j;k++) { if(newIndex[i].key<a[k]) { newIndex[i].key=a[k]; } } } //对结构体按照key值进行排序 qsort(newIndex,3,sizeof(newIndex[0]),cmp); //输入要查询的数,并调用函数进行查找 printf("输入您想要查找的数:\n"); scanf("%d",&key); k=search(key,a); //输出查找结果 if(k>0) { printf("查找成功!您要找的数在数组中的位置是:%d\n",k+1); } else{ printf("查找失败!您查找的数不在数组中。\n"); } return 0; }
运行结果为:
分块查找的优缺点分析:优点 :插入删除比较容易,无需进行大量移动。如果线性表既要快速查找又经常动态变化,则可采用分块查找。缺点:要增加一个索引表的存储空间并对初始索引表进行排序运算。