分块查找是
折半查找和
顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。
简介
分块查找是折半查找和顺序查找的一种改进方法,折半查找虽然具有很好的性能,但其前提条件时线性表顺序存储而且按照关键码排序,这一前提条件在结点树很大且表元素动态变化时是难以满足的。而顺序查找可以解决表元素动态变化的要求,但查找效率很低。如果既要保持对线性表的查找具有较快的速度,又要能够满足表元素动态变化的要求,则可采用分块查找的方法。
分块查找的速度虽然不如折半查找算法,但比顺序查找算法快得多,同时又不需要对全部节点进行排序。当节点很多且块数很大时,对索引表可以采用折半查找,这样能够进一步提高查找的速度。
分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。当增加或减少节以及节点的关键码改变时,只需将该节点调整到所在的块即可。在空间复杂性上,分块查找的主要代价是增加了一个辅助数组。
需要注意的是,当节点变化很频繁时,可能会导致块与块之间的节点数相差很大,没写快具有很多节点,而另一些块则可能只有很少节点,这将会导致查找效率的下降。
方法描述
分块查找要求把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。假设是按关键码值非递减的,那么这种块与块之间必须满足已排序要求,实际上就是对于任意的i,第i块中的所有节点的关键码值都必须小于第i+1块中的所有节点的关键码值。此外,还要建立一个索引表,把每块中的最大关键码值作为索引表的关键码值,按块的顺序存放到一个辅助数组中,显然这个辅助数组是按关键码值费递减排序的。查找时,首先在索引表中进行查找,确定要找的节点所在的块。由于索引表是排序的,因此,对索引表的查找可以采用顺序查找或折半查找;然后,在相应的块中采用顺序查找,即可找到对应的节点。
分块查找在现实生活中也很常用。例如,一个学校有很多个班级,每个班级有几十个学生。给定一个学生的学号,要求查找这个学生的相关资料。显然,每个班级的学生档案是分开存放的,没有任何两个班级的学生的学号是交叉重叠的,那么最好的查找方法实现确定这个学生所在的班级,然后再在这个学生所在班级的学生档案中查找这个学生的资料。上述查找学生资料的过程,实际上就是一个典型的分块查找。
操作步骤
step1 先选取各块中的最大关键字构成一个索引表;
step2 查找分两个部分:先对索引表进行二分查找或
顺序查找,以确定待查记录在哪一块中;
然后,在已确定的块中用顺序法进行查找。
在C语言中:
#include
struct index /*定义块的结构*/
{
int key;
int start;
int end;
} index_table[4]; /*定义结构体数组*/
int block_search(int key, int a[]) /*自定义实现分块查找*/
{
int i, j;
i = 1;
while (i <= 3 && key > index_table[i].key) /*确定在那个块中*/
i++;
if (i > 3) /*大于分得的块数,则返回0*/
return 0;
j = index_table[i].start; /*j等于块范围的起始值*/
while (j <= index_table[i].end && a[j] != key) /*在确定的块内进行查找*/
j++;
if (j > index_table[i].end) /*如果大于块范围的结束值,则说明没有要查找的数,j置0*/
j = 0;
return j;
}
main()
{
int i, j = 0, k, key, a[16];
for (i = 1; i < 16; i++)
for (i = 1; i <= 3; i++)
{
index_table[i].start = j + 1; /*确定每个块范围的起始值*/
j = j + 1;
index_table[i].end = j + 4; /*确定每个块范围的结束值*/
j = j + 4;
index_table[i].key = a[j]; /*确定每个块范围中元素的最大值*/
}
k = block_search(key, a); /*调用函数进行查找*/
if (k != 0)
else
}
平均查找长度
分块查找的平均查找长度由两部分组成,一个是对索引表进行查找的平均查找长度,一个是对快内节点进行查找的平均查找长度,总的平均查找长度为E(n)=+。线性表中共有n个节点,分成大小相等的b块,每块有s=n/b个节点。假定读索引表也采用顺序查找,只考虑查找成功的情况,并假定对每个节点的查找概率是相等的,则对每块的查找概率是1/b,对快内每个节点的查找概率是1/s。如图
上式实际上也给出了分块查找算法时对全部节点如何进行分块的原则。