• 查找算法 分享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

  • 相关阅读:
    批量拷贝局域网内的文件
    ★★★感谢伤害你的人★★★
    asp 调用子程序不能使用括号 错误解决办法
    喜欢在网上写日志的人是不是都想有朝一日被人看到?
    星语心愿
    执着
    推荐一个.NET(C#)的HTTP辅助类组件restsharp
    如何让DEV跳出的“提示试用版”的对话框不再显示
    Debugging with GDB (3) 退出gdb
    Debugging with GDB (1) 介绍
  • 原文地址:https://www.cnblogs.com/hanjun/p/2892826.html
Copyright © 2020-2023  润新知