查找算法 分享3:分塊查找


秘訣:先分塊,再匹配。分而治之

 

步驟:

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;

}

 

分塊查找的優點:

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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM