查找算法1:分块查找(索引查找)

1.原理简介
分块查找是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。当增加或减少节以及节点的关键码改变时,只需将该节点调整到所在的块即可。在空间复杂性上,分块查找的主要代价是增加了一个辅助数组。分块查找的速度虽然不如折半查找算法,但比顺序查找算法快得多,同时又不需要对全部节点进行排序。当节点很多且块数很大时,对索引表可以采用折半查找,这样能够进一步提高查找的速度。当节点变化很频繁时,可能会导致块与块之间的节点数相差很大,一些具有很多节点,而另一些块则可能只有很少节点,这将会导致查找效率的下降。分块查找要求把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。假设是按关键码值非递减的,那么这种块与块之间必须满足已排序要求,实际上就是对于任意的i,第i块中的所有节点的关键码值都必须小于第i+1块中的所有节点的关键码值。此外,还要建立一个索引表,把每块中的最大关键码值作为索引表的关键码值,按块的顺序存放到一个辅助数组中,显然这个辅助数组是按关键码值非递减排序的。查找时,首先在索引表中进行查找,确定要找的节点所在的块。由于索引表是排序的,因此,对索引表的查找可以采用顺序查找或折半查找;然后,在相应的块中采用顺序查找,即可找到对应的节点。平均查找长度:
2.C++代码实现
#define MAXL 100 //定义表中最多记录个数
#define MAXI 20 //定义索引表的最大长度
typedef int KeyType;
typedef char InfoType[10];
typedef struct
{
KeyType key; //KeyType为关键字的数据类型
InfoType data; //其他数据
} NodeType;
typedef NodeType SeqList[MAXL]; //顺序表类型
typedef struct
{
KeyType key; //KeyType为关键字的类型
int link; //指向分块的起始下标
} IdxType;
typedef IdxType IDX[MAXI]; //索引表类型
int IdxSearch(IDX I, int m, SeqList R, int n, KeyType k)
{ //分块查找算法
int low = 0, high = m - 1, mid, i, count1 = 0, count2 = 0;
int b = n / m; //b为每块的记录个数
cout << “折半查找:” << endl;
while (low <= high)
{ //在索引表中进行二分查找,找到的位置存放在low中
mid = (low + high) / 2;
cout << " 第" << count1 + 1 << “次比较:在[” << low << ", " << high << “]中比较元素R[” << mid << "] : " << R[mid].key << endl;
if (I[mid].key >= k)
high = mid - 1;
else
low = mid + 1;
count1++; //累计在索引表中的比较次数
}
if (low < m)
{ //在索引表中查找成功后,再在线性表中进行顺序查找
cout << “比较” << count1 << “次, 在第” << low << “块中查找元素” << k << endl;
i = I[low].link;
cout << “顺序查找:” << endl;
while (i <= I[low].link + b - 1 && R[i].key != k)
{
i++; count2++;
cout << R[i].key << " ";
} //count2累计在顺序表对应块中的比较次数
cout << endl;
cout << “比较” << count2 << “次, 在顺序表中查找元素” << k << endl;
if (i <= I[low].link + b - 1)
return i;
else
return -1;
}
return -1;
}

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值