什么叫做分块索引?
分块索引就是对数据集进行分块,使得分块有序,然后再对每一块建立一个索引项,从而减少索引项个数。
分块查找是折半查找和顺序查找的一种改进方法,折半查找虽然具有很好的性能,但其前提条件时线性表顺序存储而且按照关键码排序,这一前提条件在结点树很大且表元素动态变化时是难以满足的。而顺序查找可以解决表元素动态变化的要求,但查找效率很低。如果既要保持对线性表的查找具有较快的速度,又要能够满足表元素动态变化的要求,则可采用分块查找的方法。
特点:
块内无序、块间有序
索引项结构:
最大关键码、块中个数、指向块首指针
查找步骤:
1、在分块索引表中查找关键字所在的块
2、根据块首指针找到相应的块
平均查找长度ASL:
假设有n个记录平均分为m块,每块有t条记录
1、索引表平均查找长度为(m+1)/2
2、块内平均查找长度为(n+1)/2
3、总的查找长度为1/2(n/t+t) +1
最佳情况:
m=t
此时ASL = √n + 1(比顺序查找的O(n))提高不少
但是比折半查找的O(logn)相比还有不小的差距
改进空间:
因为块间有序,块间可以用折半、插值来提高手段
注意事项:
需要注意的是,当节点变化很频繁时,可能会导致块与块之间的节点数相差很大,某些具有很多节点,而另一些块则可能只有很少节点,这将会导致查找效率的下降。
以下是具体的实现代码:
#include <stdio.h>
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];
printf("please input the number:\n");
for (i = 1; i < 16; i++)
scanf("%d", &a[i]); /*输入由小到大的15个数*/
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]; /*确定每个块范围中元素的最大值*/
}
printf("please input the number which do you want to search:\n");
scanf("%d", &key); /*输入要查询的数值*/
k = block_search(key, a); /*调用函数进行查找*/
if (k != 0)
printf("success.the position is :%d\n", k); /*如果找到该数,则输出其位置*/
else
printf("no found!"); /*若未找到则输出提示信息*/
}