菜鸡笔记之——分块查找

菜鸡笔记之——分块查找+注释练习

分块查找:
前提:整个线性表可以无序,但要求分块有序,比如由一组数据:
1,3,2,6,9,8,13,15,19,32
数据整体无序,但如果将其分为四组(1,3,2),(6,9,8),(13,15,19),(32),就能保证前一块的最大值比后一块中的任意一个值小,
这称为分块有序,每一组叫做一个“块”,而每一块的最大值记为key,用key来当作查找块的索引,因此分块查找也叫做索引查找,分块查找要求分块有序使其有较大的局限性。

思路:根据块的key值检索待查找的数在哪一块中(顺序查找或二分查找),然后在这个块里顺序查找目标值。

代码实现(分块查找1.0):

# include <stdio.h>
# include <stdlib.h>

typedef struct indextable
{
    int key;
    int num[5];
    int addr;
}index;

int main(void)
{
    int array[20] = {1,4,7,3,5, 8,11,13,10,14, 15,19,18,17,20, 25,24,27,30,32};
    void find_key(index *,int *,int len,int block_num);
    index index_table[4];
    find_key(index_table,array,20,4);

    /*copy the number of the array in the index_table*/
    for (int i = 0;i<4;i++)
    {
        index_table[i].addr = 5*i;
        for(int j = 0;j<5;j++)
        {
            index_table[i].num[j] = array[5*i+j];
        }
    }

    /*search the target according to the index table*/
    int indexsearch(index *,int,int,int);
    int target,result;
    printf("enter the number you want to search:");
    scanf("%d",&target);
    result = indexsearch(index_table,4,5,target);

    /*print the search result on the screen*/
    if (result==-1)
    {
        printf("can not find this number!\n");
    }
    else
    {
        printf("%d is the %dth number\n",target,result+1);
    }

    return 0;
}
/*
**function:find_key
**description:finding the largest number in every block and reserve it into index_table[i].key
**parameter 1:the name of the index_table
**parameter 2:the name of the array
**parameter 3:the length of the array
**parameter 4:the number of the blocks
*/
void find_key(index * index_table,int * array,int len,int block_num)
{
    int i,j;
    for (i = 0;i<block_num;i++)
    {
        index_table[i].key = array[5*i];
        for(j = 1;j<5;j++)
        {
            if (array[5*i+j]>index_table[i].key)
            {
                index_table[i].key = array[5*i+j];
            }
        }
    }
}
/*
**function:indexsearch
**description:finding the target in the array according to the index table
**parameter 1:the name of the index table
**parameter 2:the number of the blocks
**parameter 3:the length of each block
**parameter 4:the number that you want to find
**return:return subscriptindex of the number if find the target,or return -1
*/
int indexsearch(index * index_table,int block_num,int block_len,int target)
{
    int i,j;
    for (i = 0;i<block_num;i++)
    {
        if (target<=index_table[i].key)
        {
            break;
        }
    }
    if (i==block_num)
    {
        return (-1);
    }
    for (j = 0;j<block_len;j++)
    {
        if (index_table[i].num[j]==target)
        {
            return (index_table[i].addr+j);
        }
    }
    return -1;
}

运行结果:
在这里插入图片描述
以上代码的缺陷比较大:
1、无法控制数组的长度和实时输入数据;
2、无法控制块的长度;
3、要求数组的长度为块的长度的整数倍,当数组长度无法被块长度整除时会 出现问题;

针对以上问题重新写代码
代码实现(分块查找2.0)

# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# define N 100

typedef struct indexblock
{
    int key;
    int number[N];
    int addr;
}index;

int main(void)
{
    void find_key(index *,int *,int,int,int);
    void distribute(index *,int *,int,int,int);
    int index_search(index *,int,int,int,int);

    int array_len,block_len;
    printf("please enter the length of the array:");
    scanf("%d",&array_len);
    int * array = NULL;
    array = (int *)malloc(sizeof(int)*array_len);
    if (array==NULL)
    {
        printf("error!\n");
        exit(-1);
    }
    /*enter the number*/
    printf("please input %d numbers in specific sequence:\n",array_len);
    for (int i = 0;i<array_len;i++)
    {
        scanf("%d",array+i);
    }
    printf("the length of each block:");
    scanf("%d",&block_len);

    /*finding the key of each block*/
    int block_num = ceil((float)array_len/(float)block_len);    /*upward rounding*/
    printf("block_num :%d\n",block_num);
    index index_table[block_num];
    find_key(index_table,array,array_len,block_num,block_len);

    /*distribute the numbers*/
    distribute(index_table,array,array_len,block_num,block_len);

    /*search the number according to the index table*/
    int target,result;
    printf("which number you want to search:");
    scanf("%d",&target);
    result = index_search(index_table,array_len,block_num,block_len,target);
    printf("%d is the %dth number\n",target,result+1);

    /*release dynamically allocated memory*/
    free(array);
    return 0;
}
/*
**function:find_key
**description:finding the largest number of each block and reserve it in index_table[i].key
**parameter 1: the name of the index table
**parameter 2: the name of the array
**parameter 3: the length of the array
**parameter 4: the number of the block of the index table
**parameter 5: the length of each block
*/
void find_key(index * index_table,int * array,int array_len,int block_num,int block_len)
{
    int i,j;
    for (i = 0;i<block_num;i++)
    {
        index_table[i].key = array[i*block_len];
        for (j = block_len*i+1;j<block_len*(i+1);j++)
        {
            if (j==array_len)
            {
                return;
            }
            if (index_table[i].key<array[j])
            {
                index_table[i].key = array[j];
            }
        }
    }
}
/*
**function: distribute
**description: put the number of the array into the index table
**parameter 1: the name of the index table
**parameter 2: the name of the array
**parameter 3: the length of the array
**parameter 4: the number of the block of the index table
**parameter 5: the length of each block
*/
void distribute(index * index_table,int * array,int array_len,int block_num,int block_len)
{
    int i,j;
    for (i = 0;i<block_num;i++)
    {
        index_table[i].addr = i*block_len;
        for (j = 0;j<block_len;j++)
        {
            if (i*block_len+j>=array_len)
            {
                return;
            }
            index_table[i].number[j] = array[i*block_len+j];
        }
    }
}
/*
**function: index_search
**description: finding the place of the target number
**parameter 1: the name of the index table
**parameter 2: the length of the array
**parameter 3: the number of the block of the index table
**parameter 4: the length of each block
**parameter 5: the number which you want to search
**return: the serial number of the target number in the array
*/
int index_search(index * index_table,int array_len,int block_num,int block_len,int target)
{
    int i,j;
    for (i = 0;i<block_num;i++)
    {
        if (target<=index_table[i].key)
        {
            break;
        }
    }
    if (i==block_num)
    {
        printf("can not find this number!\n");
        exit(0);
    }

    /*if the number is in the final block*/
    if (i==block_num-1)
    {
        for (j = 0;j<(array_len-(block_num-1)*block_len);j++)
        {
            if (index_table[i].number[j]==target)
            {
                return (index_table[i].addr+j);
            }
        }
        if (j==(array_len-(block_num-1)*block_len))
        {
            printf("can not find this number!\n");
            exit(0);
        }
    }
    else
    {
        for (j = 0;j<block_len;j++)
        {
            if (target==index_table[i].number[j])
            {
                return (index_table[i].addr+j);
            }
        }
        if (j==block_len)
        {
            printf("can not find this number!\n");
            exit(0);
        }
    }
}

以一开始举的例子为例:
输入1,3,2,6,9,8,13,15,19,32,查找值32
运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值