文字描述
分块查找又称为索引顺序查找,是顺序查找的一种改进方法.在此查找算法中,除表本身外, 还需要建立一个”索引表”.索引表中包括两项内容:关键字项(其值为该字表内的最大关键字)和指针项(指示该子表的第一个记录在表中位置)。索引表按关键字有序,则表或者有序或者分块有序。所谓“分块有序”指的是第二个子表中所有记录的关键字均大于第一个子表中的最大关键字,第三个子表中的所有关键字均大于第二个子表中的最大关键字,,,,以此类推。
因此分块查找算法需分两步进行:
先确定待查记录所在的块(子表)。由于索引项组成的索引表按关键字有序,则确定块的查找可以用顺序查找,也可以用折半查找。
再在块中顺序查找。如果块中记录是任意排列的,就只能是顺序查找。
示意图
算法分析
分块查找的平均查找长度为ASLbs = Lb+Lw, 其中Lb为查找索引表确定所在块的平均查找长度,Lw为在块中查找元素的平均查找长度。
一般情况下,为进行分块查找,可以将长度为n的表均匀地分成b块,每块含有s个记录,即b=[n/s];又假定表中每个记录的查找概率相等,则每块查找的概率为1/b,块中每个记录的查找概率为1/s。
若用顺序查找确定所在块,顺序查找子表中的元素,则分块查找的平均查找长度为
若用折半查找确定所在块,顺序查找子表中的元素,则分块查找的平均查找长度为
代码实现
1 //./a.out 5 13 19 21 37 56 64 75 80 88 92
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #define DEBUG
8
9 #define MAX_SIZE 50
10 #define BLOCK_SIZE 5
11
12 typedef struct{
13 int start;
14 int end;
15 int key;
16 }Index_K;
17
18
19 //分块查找算法
20 int block_search(int key, int a[], Index_K index_k[], int len)
21 {
22 int i = 0;
23 int j = 0;
24 int k = -1;
25 //顺序查找确定所在块
26 while((index_k[i].start>=0) && (key>index_k[i].key))
27 i+=1;
28 if(index_k[i].start < 0){
29 return k;
30 }
31 //顺序查找子表中的元素
32 for(j = index_k[i].start; j<=index_k[i].end; ++j){
33 if(key == a[j])
34 k = j;
35 }
36 return k;
37 }
38
39 //顺序打印整型数组中的元素
40 void print(int a[], int len)
41 {
42 int i = 0;
43 for(i=0; i<len; i++){
44 printf("[%d]:%d ", i, a[i]);
45 }
46 printf("\n");
47 return;
48 }
49
50 int main(int argc, char *argv[])
51 {
52 if(argc < 2)
53 return -1;
54
55 int a[MAX_SIZE] = {0};
56 Index_K index_k[MAX_SIZE/BLOCK_SIZE+1];
57
58 int i = 0, j = 0, len = 0, key = 0;
59 for(i=1; i<argc; i++){
60 a[i-1] = atoi(argv[i]);
61 }
62 len = i-1;
63
64 #ifdef DEBUG
65 printf("输入数据:");
66 print(a, len);
67 #endif
68 printf("索引表:\n");
69 i = j = 0;
70 while(i<len){
71 index_k[j].start = i;
72 index_k[j].end = ((i+BLOCK_SIZE)>(len-1))?(len-1):(i+BLOCK_SIZE);
73 index_k[j].key = ((i+BLOCK_SIZE)>(len-1))?a[len-1]:a[i+BLOCK_SIZE];
74 printf("index_k[%d].start=%d .end=%d .key=%d\n", j, index_k[j].start, index_k[j].end, index_k[j].key);
75 j += 1;
76 i += BLOCK_SIZE;
77 i += 1;
78 }
79 index_k[j].start = index_k[j].end = index_k[j].key = -1;
80
81 while(1){
82 printf("输入key:");
83 scanf("%d", &key);
84 if(key<0)
85 break;
86 printf("key(%d) 位于 %d\n", key, block_search(key, a, index_k, len));
87 }
88 return 0;
89 }
分块查找(索引顺序表)
运行