#include <bits/stdc++.h>
using namespace std;
struct index
{
int key;
int start;
} newIndex[3];
int search(int key, int* a)
{
int i = 0, startValue = newIndex[i].start;
while (i<3 && key>newIndex[i].key)i++;
if (i >= 3) return -1;
while (startValue <= startValue + 5 && a[startValue] != key)startValue++;
if (startValue > startValue + 5)return -1;
return startValue;
}
int cmp(const void* a, const void* b)
{
return (*(struct index*)a).key > (*(struct index*)b).key ? 1 : -1;
}
int main(void)
{
int a[] = { 33,42,44,38,24,48, 22,12,13,8,9,20, 60,58,74,49,86,53 }, j = -1, key;
for (int i = 0; i < 3; i++)
{
newIndex[i].start = j + 1;
j += 6;
for (int k = newIndex[i].start; k <= j; k++)if (newIndex[i].key < a[k])newIndex[i].key = a[k];
}
qsort(newIndex, 3, sizeof(newIndex[0]), cmp);
cin >> key;
cout << search(key, a);;
}
思路:
分块查找,也叫索引顺序查找,算法实现除了需要查找表本身之外,还需要根据查找表建立一个索引表。例如图 1,给定一个查找表,其对应的索引表如图所示:
以图 1 中的查找表为例,假设要查找关键字 38 的具体位置。首先将 38 依次和索引表中各最大关键字进行比较,因为 22 < 38 < 48,所以可以确定 38 如果存在,肯定在第二个子表中。
由于索引表中显示第二子表的起始位置在查找表的第 7 的位置上,所以从该位置开始进行顺序查找,一直查找到该子表最后一个关键字(一般将查找表进行等分,具体子表个数根据实际情况而定)。结果在第 10 的位置上确定该关键字即为所找。
提示:在第一步确定块(子表)时,由于索引表中按照关键字有序,所有可以采用折半查找算法。而在第二步中,由于各子表中关键字没有严格要求有序,所以只能采用顺序查找的方式。