分块查找法要求将列表组织成以下索引顺序结构:
首先将列表分成若干个块(子表)。一般情况下,块的长度均匀,最后一块可以不满。
每块中元素任意排列,即块内无序,但块与块之间有序。
构造一个索引表。其中每个索引项对应一个块并记录每块的起始位置,和每块中最大
关键字(或最小关键字)。索引表按关键字有序排列。
下图所示为一个索引顺序表。其中包括三个块,第一个块的起始地址为 0,块内最
大关键字为 25;第二个块的起始地址为 5,块内最大关键字为 58;第三个块的起始地址为
10,块内最大关键字为 88。
分块查找的基本过程如下:
(1)首先,将待查关键字 K 与索引表中的关键字进行比较,以确定待查记录所在的
块。具体的可用顺序查找法或折半查找法进行。
(2)进一步用顺序查找法,在相应块内查找关键字为 K的元素。
分块查找是顺序查找的一种改进方法。首先需要对数组进行分块,分块查找需要建立一个“索引表”。索引表分为m块,每块含有N/m个元素,块内是无序的,块间是有序的,例如块2中最大元素小于块3中最小元素。
先用二分查找索引表,确定需要查找的关键字在哪一块,然后再在相应的块内用顺序查找。分块查找又称为索引顺序查找。
时间复杂度:O(log(m)+N/m)
1 //分块查找 2 template<class T>//索引表 3 struct INDEXTable 4 { 5 T key; 6 int link; 7 }; 8 9 template<class T> IndexOrderSearch(INDEXTable<T> *indexTable,T *x, int N, int m, T keyword)// indexTable为索引表,x为原数组,N为数组大小,m为块大小 10 { 11 int L = (N+m-1)/m; 12 int i = 0; 13 while(i < L && indexTable[i].key < keyword) 14 i++; 15 if(i == L) 16 return -1; 17 else 18 { 19 int j = indexTable[i].link; 20 for(j; j<indexTable[i].link + m;j++) 21 if(x[j] == keyword) 22 return j; 23 } 24 return -1; 25 }