分块查找_legend



分块查找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;

 

}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值