分块索引(查找)

什么叫做分块索引?

    分块索引就是对数据集进行分块,使得分块有序,然后再对每一块建立一个索引项,从而减少索引项个数。
    分块查找是折半查找和顺序查找的一种改进方法,折半查找虽然具有很好的性能,但其前提条件时线性表顺序存储而且按照关键码排序,这一前提条件在结点树很大且表元素动态变化时是难以满足的。而顺序查找可以解决表元素动态变化的要求,但查找效率很低。如果既要保持对线性表的查找具有较快的速度,又要能够满足表元素动态变化的要求,则可采用分块查找的方法。

特点:

块内无序、块间有序

索引项结构:

最大关键码、块中个数、指向块首指针

这里写图片描述

查找步骤:

1、在分块索引表中查找关键字所在的块
2、根据块首指针找到相应的块

平均查找长度ASL:

假设有n个记录平均分为m块,每块有t条记录
    1、索引表平均查找长度为(m+1)/2
    2、块内平均查找长度为(n+1)/2
    3、总的查找长度为1/2(n/t+t) +1

最佳情况:

m=t
    此时ASL = √n + 1(比顺序查找的O(n))提高不少
    但是比折半查找的O(logn)相比还有不小的差距
改进空间:
因为块间有序,块间可以用折半、插值来提高手段

注意事项:

需要注意的是,当节点变化很频繁时,可能会导致块与块之间的节点数相差很大,某些具有很多节点,而另一些块则可能只有很少节点,这将会导致查找效率的下降。

以下是具体的实现代码:

#include <stdio.h>
struct index /*定义块的结构*/
{
    int key;
    int start;
    int end;
} index_table[4]; /*定义结构体数组*/

int block_search(int key, int a[]) /*自定义实现分块查找*/
{
    int i, j;
    i = 1;
    while (i <= 3 && key > index_table[i].key) /*确定在那个块中*/
        i++;
    if (i > 3) /*大于分得的块数,则返回0*/
        return 0;
    j = index_table[i].start; /*j等于块范围的起始值*/
    while (j <= index_table[i].end && a[j] != key) /*在确定的块内进行查找*/
        j++;
    if (j > index_table[i].end) /*如果大于块范围的结束值,则说明没有要查找的数,j置0*/
        j = 0;
    return j;
}

main() 
{
    int i, j = 0, k, key, a[16];
    printf("please input the number:\n");
    for (i = 1; i < 16; i++)
        scanf("%d", &a[i]);                   /*输入由小到大的15个数*/
    for (i = 1; i <= 3; i++)
    {
        index_table[i].start = j + 1;         /*确定每个块范围的起始值*/
        j = j + 1;
        index_table[i].end = j + 4;           /*确定每个块范围的结束值*/
        j = j + 4;
        index_table[i].key = a[j];            /*确定每个块范围中元素的最大值*/
    }
    printf("please input the number which do you want to search:\n");

    scanf("%d", &key);                        /*输入要查询的数值*/

    k = block_search(key, a);                 /*调用函数进行查找*/
    if (k != 0)
        printf("success.the position is :%d\n", k); /*如果找到该数,则输出其位置*/
    else
        printf("no found!");                    /*若未找到则输出提示信息*/
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值