分块查找BlockingSearch(索引顺序查找):二分查找与顺序查找的组合
(零)类似于元素分类,最大间隔问题,查看将一个数组中的元素,分为多个桶。
查看:http://blog.csdn.net/legend050709/article/details/38986157
(一)思想:
(1)构建查找表
将查找表分为若干块,块内无序,块间有序;
即第一块中的关键字小于第二块中的关键字,第二小于第三,.....;
(2)建立一个索引表,索引表中的每个元素含有各块的最大关键字和各块中的第一个元素在查找表中的地址,索引表是按关键字有序排序的。
注:第i块的最后一个元素的地址,就是第i+1块的第一个元素的地址-1;
(二)查找过程:
(1)在索引表中确定待查记录的块,可以顺序查找或二分查找索引表;
(2)在块内顺序查找;
(三)举例:
(四)代码实现:
#include <stdio.h>
struct index { //定义块的结构
int key;
int start;
int end;
} newIndex[4]; //定义结构体数组
int search(int key, int a[]);
int main(int argc, const char * argv[])
{
//输出已知数组
int i, j=-1, k, key;
int a[] = {146,219,254,315,336, 358,795,876,951,999, 12,25,33,36,57};
//数组已经是一个查找表,即已经分好块了。块内无序,块间有序。
printf("已知有一组数\n");
for (i=0; i<15; i++) {
printf("%d ",a[i]);
if ((i+1)%5==0 && i<14) {
printf(" | ");
}
}
printf("\n\n");
//确认模块的起始值和最大值
for (i=0; i<3; i++) {
newIndex[i].start = j+1; //确定每个块范围的起始值
j++;
newIndex[i].end = j+4; //确定每个块范围的结束值
j += 4;
newIndex[i].key = a[j]; //确定每个块范围中元素的最大值
//已经分好块了,块的最后一个元素时最大的元素。
printf("newIndex[%d].start = %d\n",i, newIndex[i].start);
printf("newIndex[%d].end = %d\n",i, newIndex[i].end);
printf("newIndex[%d].key = %d\n\n",i, newIndex[i].key);
}
//输入要查询的数,并调用函数进行查找
printf("请输入您想要查找的数:\n");
scanf("%d", &key);
k= search(key, a);
//输出查找的结果
if (k>0) {
printf("查找成功!您要找的数在数组中的位置是:%d\n",k+1);
}else{
printf("查找失败!您要找的数不在数组中。\n");
}
return 0;
}
int search(int key, int a[]){
int i, startValue;
i= 0;
while (i<3 && key>newIndex[i].key) { //确定在哪个块中,遍历每个块,确定key在哪个块中
i++;
}
if (i>=3) { //大于分得的块数,则返回0
return -1;
}
startValue = newIndex[i].start; //startValue等于块范围的起始值
while (startValue<=newIndex[i].end && a[startValue]!=key){ //在确定的块内进行查找
startValue++;
}
if (startValue>newIndex[i].end) { //如果大于块范围的结束值,则说明没有要查找的数,startValue置为0
startValue = -1;
}
return startValue;
}