分块查找

分块查找(索引表查找)

分块查找是折半查找和顺序查找的一种改进方法,折半查找虽然具有很好的性能,
但其前提条件时线性表顺序存储而且按照关键码排序,这一前提条件在结点树很
大且表元素动态变化时是难以满足的。而顺序查找可以解决表元素动态变化的要求,
但查找效率很低。如果既要保持对线性表的查找具有较快的速度,又要能够满足表
元素动态变化的要求,则可采用分块查找的方法。分块查找的速度虽然不如折半查找算法,
但比顺序查找算法快得多,同时又不需要对全部节点进行排序。当节点很多且块数很大时,
对索引表可以采用折半查找,这样能够进一步提高查找的速度。 

 
分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化
的情况。当增加或减少节以及节点的关键码改变时,只需将该节点调整到所在的块即可。
在空间复杂性上,分块查找的主要代价是增加了一个辅助数组。
 由上图我们可以看出,这个表中有18个元素,我们将其分为了三个块,每个块有6个元素。
使用分块查找的要求:
1:索引表必须要有序,而每一个索引块不必有序;
2:第一个索引块中的任意元素必须小于第二个索引块中的任意元素,第二个索引块中的任意
元素必须小于第三个索引块中任意元素。。。。。依次类推;
步骤:
1:建立辅助数组,即索引表。
2:找出每个索引块中的最大元素,依次存入到索引表中。
3:在索引表中找到key所存在的索引块(目标索引块)。(顺序查找)。
4:在目标索引块中查找key(顺序查找),若存在输出对应的下标。
代码:
#include<iostream>
using namespace std;
int fenkuai_search(int A[],int n,int m,int key)
{
    int max=0;//用来记录每个索引块中的最大值 
    int M=0;
    int B[n/m-1];//建立索引表数组;
    int j=0; 
    for(int i=0;i<n;i++)//寻找每一个索引块中的最大值; 
    {
        M++;
        if(M<=m&&A[i]>max) 
           max=A[i];
        if(M==m)
        {
            B[j]=max;
            j++;
            M=0;
        }
    }
    for(int i=0;i<n/m;i++)//在索引表中查找索引块 
    {
        if(key<=B[i])//找到对应的索引块 
        {
            for(int x=i*m;x<(i+1)*m;x++)//在对应的索引块中查找key; 
            {
                if(A[x]==key) return x;
            }
        }
     } 
     return -1;
}
int main()//举例用法 
{
    int A[]={22,12,13,8,9,20,33,42,44,38,24,48,60,58,74,49,86,53};
    int key;
    cin>>key;
    int x=fenkuai_search(A,18,3,key); 
    if(x!=-1) cout<<key<<"元素所在的位置为:"<<x;
    else cout<<"该数组中没有该元素"; 
    return 0;
}
 
原文地址:https://www.cnblogs.com/zhoubo123/p/11302216.html