秘訣:先分塊,再匹配。分而治之
步驟:
1.先取各塊中的最大關鍵字構成一個索引表。
2.查找分為兩部分,先對索引表進行二分查找或是順序查找,以確定待查記錄在哪一塊中。
3.然后,在已經確定的塊中用順序法進行查找。
#import <Foundation/Foundation.h>
struct indexBlock // 定義塊的結構
{
int key;
int start;
int end;
} indexBlock[ 4]; // 定義結構體數組
int main( int argc, const char * argv[])
{
@autoreleasepool {
int j = - 1, k, x;
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
printf( " 已知有一組數:\n ");
for ( int i = 0; i < 15; i++) {
printf( " %d ", a[i]);
}
printf( " \n ");
for ( int i = 0; i < 3; i++) {
indexBlock[i].start = j + 1; // 確定每個塊范圍的起始值
j = j + 1;
indexBlock[i].end = j + 4; // 確定每個塊范圍的結束值
j = j + 4;
indexBlock[i].key = a[j]; // 確定每個塊范圍中元素的最大值
}
printf( " 請輸入你要查找的數:\n ");
scanf( " %d ", &x);
k = blockSearch(x, a);
if (k >= 0) {
printf( " 查找成功!你要查找的數在數組中的位置是:%d\n ", k+ 1);
}
else{
printf( " 查找失敗!你要查找的數不在數組中。\n ");
}
}
return 0;
}
int blockSearch( int x, int a[]){
int i = 0;
int j;
while (i< 3 && x>indexBlock[i].key) { // 確定在哪個塊中
i++;
}
if (i >= 3) { // 大於分的塊數,則返回-1,找不到該數
return - 1;
}
j = indexBlock[i].start; // j等於塊范圍的起始值
while (j<=indexBlock[i].end && a[j]!=x) { // 在確定的塊內進行查找
j++;
}
if (j > indexBlock[i].end) { // 如果大於塊范圍的結束值,則說明沒有要查找的數,j置為-1
j = - 1;
}
return j;
struct indexBlock // 定義塊的結構
{
int key;
int start;
int end;
} indexBlock[ 4]; // 定義結構體數組
int main( int argc, const char * argv[])
{
@autoreleasepool {
int j = - 1, k, x;
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
printf( " 已知有一組數:\n ");
for ( int i = 0; i < 15; i++) {
printf( " %d ", a[i]);
}
printf( " \n ");
for ( int i = 0; i < 3; i++) {
indexBlock[i].start = j + 1; // 確定每個塊范圍的起始值
j = j + 1;
indexBlock[i].end = j + 4; // 確定每個塊范圍的結束值
j = j + 4;
indexBlock[i].key = a[j]; // 確定每個塊范圍中元素的最大值
}
printf( " 請輸入你要查找的數:\n ");
scanf( " %d ", &x);
k = blockSearch(x, a);
if (k >= 0) {
printf( " 查找成功!你要查找的數在數組中的位置是:%d\n ", k+ 1);
}
else{
printf( " 查找失敗!你要查找的數不在數組中。\n ");
}
}
return 0;
}
int blockSearch( int x, int a[]){
int i = 0;
int j;
while (i< 3 && x>indexBlock[i].key) { // 確定在哪個塊中
i++;
}
if (i >= 3) { // 大於分的塊數,則返回-1,找不到該數
return - 1;
}
j = indexBlock[i].start; // j等於塊范圍的起始值
while (j<=indexBlock[i].end && a[j]!=x) { // 在確定的塊內進行查找
j++;
}
if (j > indexBlock[i].end) { // 如果大於塊范圍的結束值,則說明沒有要查找的數,j置為-1
j = - 1;
}
return j;
}


分塊查找的優點:
1.在表中插入或刪除一個記錄時,只要找到該記錄所屬的塊,就在該塊內進行插入和刪除運算。
2.因為塊內記錄的存放是任意的,所以插入或刪除比較容易,無須移動大量記錄。
缺點:分塊查找算法的主要代價是增加一個輔助數組的存儲空間。
補充:
#include <stdio.h> struct index { //定義塊的結構 int key; int start; int end; } newIndex[4]; //定義結構體數組 int search(int key, int a[]); int main(int argc, const char * argv[]) { //輸出已知數組 int i, j=-1, k, key; int a[] = {146,219,254,315,336, 358,795,876,951,999, 12,25,33,36,57}; printf("已知有一組數\n"); for (i=0; i<15; i++) { printf("%d ",a[i]); if ((i+1)%5==0 && i<14) { printf(" | "); } } printf("\n\n"); //確認模塊的起始值和最大值 for (i=0; i<3; i++) { newIndex[i].start = j+1; //確定每個塊范圍的起始值 j++; newIndex[i].end = j+4; //確定每個塊范圍的結束值 j += 4; newIndex[i].key = a[j]; //確定每個塊范圍中元素的最大值 printf("newIndex[%d].start = %d\n",i, newIndex[i].start); printf("newIndex[%d].end = %d\n",i, newIndex[i].end); printf("newIndex[%d].key = %d\n\n",i, newIndex[i].key); } //輸入要查詢的數,並調用函數進行查找 printf("請輸入您想要查找的數:\n"); scanf("%d", &key); k = search(key, a); //輸出查找的結果 if (k>0) { printf("查找成功!您要找的數在數組中的位置是:%d\n",k+1); }else{ printf("查找失敗!您要找的數不在數組中。\n"); } return 0; } int search(int key, int a[]){ int i, startValue; i = 0; while (i<3 && key>newIndex[i].key) { //確定在哪個塊中,遍歷每個塊,確定key在哪個塊中 i++; } if (i>=3) { //大於分得的塊數,則返回0 return -1; } startValue = newIndex[i].start; //startValue等於塊范圍的起始值 while (startValue<=newIndex[i].end && a[startValue]!=key) { //在確定的塊內進行查找 startValue++; } if (startValue>newIndex[i].end) { //如果大於塊范圍的結束值,則說明沒有要查找的數,startValue置為0 startValue = -1; } return startValue; }
已知有一組數
146 219 254 315 336 | 358 795 876 951 999 | 12 25 33 36 57
newIndex[0].start = 0
newIndex[0].end = 4
newIndex[0].key = 336
newIndex[1].start = 5
newIndex[1].end = 9
newIndex[1].key = 999
newIndex[2].start = 10
newIndex[2].end = 14
newIndex[2].key = 57
請輸入您想要查找的數:
999
查找成功!您要找的數在數組中的位置是:10
