查找算法——分块查找 你掌握了吗?

在这里插入图片描述
停课不停学 我们在努力

齐心协力 一起抗疫

1.分块查找

分块查找又称索引顺序查找,是介于顺序查找和折半查找之间的查找算法,它是顺序查找算法的一种改进算法。

2.算法说明

运行分块查找程序,系统会输出要查找的数组,提示用户输入想要查找的数。输入后系统判断并输出有无此数,如果该函数存在的话系统还会输出其在数组中的位置。程序运行结果如图所示。

在这里插入图片描述

3.算法分析

分块查找算法的描述是将n个数据元素“ 按块有序”划分为m块(m≤n)。每一块中的结点不必有序,但块与块之间必须“按块有序”;即第一 块中任一 元 素的关键字都必须小于第二块中任一元素的关键字; 而第二块中任一元素的关键字又都必须小于第三块中的任一元 素的关键…

操作步骤:

(1)选取各块中的最大关键字构成-一个索引表。

(2)查找分为两部分,先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中。

(3)然后,在已经确定的块中用顺序法进行查找。

分块查找的平均查找长度ASLbs。

分块查找是两次查找过程,整个查找过程的平均查找长度是两次查找的平均查找长度之和。其计算公式为:

ASLbs=Lb+Lw

其中Lb表示查找索引表以确定记录所在块的平均查找长度; Lw表示在查找到的块中, 查找记录的平均查找长度。

①以二分查找来确定块,分块查找成功时的平均查找长度ASLbs

=Lb+Lw

=lg(b+1)-1+(s+1)/2

=lg(n/s+1)+s/2。

②以顺序查找来确定块,分块查找成功时的平均查找长度ASLos=Lp+Lw

=(b+1)/2+(s+1)/2

= (s2+2s+n)/(2s)。

分块查找中块的大小:可根据表的特征进行分块,不一定要将线性表分成大小相等的若干块。各块可放在不同的向量中,也可将每一块存放在一个单链表中。

分块查找的优点:

(1)在表中插入或删除一个个 记录时,只要找到该记录所属的块,就在该块内进行插入和删除运算。

(2)因块内记录的存放是任意的,所以插入或删除比较容易,无须移动大量记录。分块查找算法的主要代价是增加一个辅助数组的存储空间。

实现过程

本程序实现过程如下:

(1)启动Microsoft Visual C++ 6.0。

(2)选择file/new菜单项,在弹出的对话框里选择files/C++ Source File选项,填写文件名,设置存储路径,单击OK按钮。

(3)编写程序代码。

定义结构体类型和变量,程序代码如下:

struct index

/*定义块的结构*/

int key;

int start;

int end;

} index[4];

/*定义结构体数组*/

变量定义并输出已知数组,程序代码如下:

int i,j=-1, k, key;

/*定义变量*/

int a[]={42,63,82,9,111,146,219,254,325,336,348,795,876,951,998}; 

/*已知的一组数*/

printf("已知有一组数\n");

for(i=0;i<15;i++)

printf("%d ",a[i]);

/*输出已知数组*/

printf("\n"); 

确认模块的起始值和最大值,程序代码如下:

for(i=0;i<3; i++)

{

    index[i].start= j+1;

/*确定每个块范围的起始值*/

    j=j+ 1;

        index[i].end=j+4;

/*确定每个块范围的结束值*/

        j=j+4;

        index[i].key = a[j]; 

/*确定每个块范围中元素的最大值*/

}

输入要查询函数,并调用函数进行查找。程序代码如下:

printf(" 请输入您想要查找的数:\n");

scanf("%d", &key);

/*输入要查询的数值*/

k = search(key, a);

/*调用函数进行查找*/

输出查找结果,程序代码如下:

if(k>=0)

    printf("查找成功!您要找的数字数组中的位置是:%d\n", k+1); 

/*如果找到该数,则输出其位置*/

else

printf("查找失败!您要找的数不在数组中。\n");

/*若未找到则输出提示信息*/

}

定义函数search(实现分块查找,程序代码如下:

int search(int key, int a[])

/*自定义实现分块查找*/

{

int i,j; 

i= 0;

while (i < 3 && key > index[i].key)

/*确定在哪个块中*/

    i++;

if(i>=3);

/*大于分得的块数,则返回0*/

    return -1;

j = index[i].start;

/*j等于块范围的起始值*/

while(i <= index[i].end && a[j] != key)

/*在确定的块内进行查找*/

    j++;

if (i > index[i].end)

/*如果大于块范围的结束值,则说明没有要查找的数,j值0*/

    j= -1;

return j;

}

在这里插入图片描述
或许命运有时候会不公,但只要我们努力地去奋斗,时刻谨记“奋斗”二字,我们就能“扼住命运的咽喉”,改写命运。 加油!!

扫描二维码

关注我们
在这里插入图片描述
微信号 : wudaxiaoyuan

微信公众号:物达校园

让我知道你

再看

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值