索引表中折半查找,块内进行顺序查找
#include <stdio.h>
#include <malloc.h>
#define MAXL 100 //最大长度
typedef int KeyType; //定义关键字类型为int
typedef char InfoType;
typedef struct
{
KeyType key; //关键字项
InfoType data; //其他数据项,类型为InfoType
} RecType; //查找元素的类型
void CreateList(RecType R[], KeyType keys[], int n) //创建顺序表
{
for (int i = 0; i < n; i++) //R[0..n-1]存放排序记录
R[i].key = keys[i];
}
void DispList(RecType R[], int n) //输出顺序表
{
for (int i = 0; i < n; i++)
printf("%d ", R[i].key);
printf("\n");
}
#define MAXI 20 //定义索引表的最大长度
typedef struct
{
KeyType key; //KeyType为关键字的类型
int link; //指向分块的起始下标
} IdxType; //索引表元素类型
int IdxSearch(IdxType I[], int b, RecType R[], int n, int s,KeyType k) //分块查找
{
//s为每块的元素个数,应为n/b取上界
int count1 = 0, count2 = 0;
int low = 0, high = b - 1, mid, i;
printf("(1)先在索引表中折半查找\n");
while (low <= high) //在索引表中进行折半查找,找到的位置为high+1
{
mid = (low + high) / 2;
printf(" 第%d次比较:在[%d,%d]中,比较索引表中元素I[%d],即比较元素R[%d]:%d\n", count1 + 1, low, high,mid, mid*s, R[mid*s].key);
if (I[mid].key >= k)
high = mid - 1;
else
low = mid + 1;
count1++; //count1累计在索引表中的比较次数
}
printf("\n比较%d次,还需要在索引表中第%d块中查找元素%d\n", count1, low, k);
//应在索引表的high+1块中,再在主数据表中进行顺序查找
i = I[high + 1].link; //找到对应的块
printf("\n(2)后在索引表的对应块中顺序查找:\n ");
while (i <= I[high + 1].link + s - 1)
{
printf(" %d ", R[i].key);
count2++; //count2累计在顺序表对应块中的比较次数
if (R[i].key == k) break;
i++;
}
printf("比较%d次,在顺序表中查找元素%d\n", count2, k);
if (i <= I[high + 1].link + s - 1)
return i + 1; //查找成功,返回该元素的逻辑序号
else
return 0; //查找失败,返回0
}
int main()
{ KeyType k = 71;//设置待查找的数
RecType R[MAXL];
IdxType I[MAXI]; //前面宏定义#define MAXI 20
int n = 25, i;
int a[] = { 8,14,6,9,10,18,22,19,34,31,40,38,54,56,66,68,71,78,80,85,94,88,96,87,100 };
//需要注意索引表中的前一块的所有元素都要比后一块的所有元素小,观察上面的数组,可得块内元素的个数可为:5,6,但不能为7
CreateList(R, a, n); //建立顺序表
int t,j=0,temp;
int s=6;//索引表中块内元素的个数,可以自行设置,但是在设置时,需要注意索引表中的前一块的所有元素都要比后一块的所有元素小,
int b;//索引表的长度,即索引表中块的个数
if (n%s)//确定索引表的长度,即索引表中块的个数
b = n / s + 1;
else
b = n / s;
for (t = 0; t < b; t++)
{
temp = a[t*s];
I[t].link = t * s ;
for (j= 0; j < s; j++)
{
if (temp <= a[t * s + j])
{
temp = a[t * s + j];
I[t].key = temp;
}
}
}
//I[0].key = 14; I[0].link = 0; //建立索引表
//I[1].key = 34; I[1].link = 5;
//I[2].key = 66; I[2].link = 10;
//I[3].key = 85; I[3].link = 15;
//I[4].key = 100; I[4].link = 20;
printf("关键字序列:");
for (i = 0; i < n; i++)
{
printf("%4d", R[i].key);
if (((i + 1) % s) == 0) printf(" ");
if (((i + 1) % (2*s)) == 0) printf("\n\t ");
}
printf("\n");
printf("查找%d的比较过程如下:\n", k);
if (i=IdxSearch(I, b, R, 25,s, k))
printf("元素%d的位置是第%d个数\n", k, i);
else
printf("元素%d不在表中\n", k);
return 1;
}