查找算法-分块算法

查找算法-分块算法


        查找算法主要有三种:

        线性查找、二分查找、分块查找

 

        线性查找效率最慢,可对无序列表进行查找、

        二分查找效率最快,只能针对有序列表进行查找

        分块查找的效率在线性查找和二分查找之间,可对无序列表进行查找。


     分块查找的思路:

       分块查询中,每个块中元素不一定有序的,块间是有序的。 

分块又称索引顺序查找,这是顺序查找的一种改进方法,用于在分块有序表中进行查找 。

主表:存储数据的表,长度n;

索引表:将主表分块,每块长s,找出每块中的关键字最大值,并且保存该块中所有数据在主表中的索引

(1)分块:将n个数据元素“按块有序”划分为m块。

每一块中的结点不必有序,但块与块之间必须“按块有序”;即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素。每个块中元素不一定是有序的。

(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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕容屠苏

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值