插分查找,斐波那契查找,分块查找(有序表的查找)

一、插分查找

 

在一个0~10000之间的100个元素从小到大均匀分布的数组中查找5,我们自然会考虑从数组下标较小的开始查找,因此二分查找还有提高空间。

mid = (low+high)/2 = low+1/2(high-low)。在这公式中我们将这个1/2进行修改:

mid = low + (key-a[low])/a[high]-a[low](high-low)。

比如在a[11] = {0,1,16,4,35,47,59,62,73,88,99},查找16,按照原来二分查找需要四次,改进后为:二次。其中mid= 1+ (16-1)/(99-1) *(10-1) = 2.377.

针对代码只需将:mid = (low+high)/2  改为   mid = low + (high-low)*(key-a[low])/(a[high]-a[low])即可。

 

int Search_Bin(SSTable ST, KeyType key) //插分查找
{ /* 在有序表ST中插分查找其关键字等于key的数据元素。若找到,则函数值为 */
  /* 该元素在表中的位置,否则为0。 */
	int low, high, mid;
	low = 1; /* 置区间初值 */
	high = ST.length;
	while (low <= high)
	{
		mid = low + (high-low)*(key-a[low])/(a[high]-a[low]);
		if EQ(key, ST.elem[mid].key)  /* 找到待查元素 */
			return mid;
		else if LT(key, ST.elem[mid].key)
			high = mid - 1; /* 继续在前半区间进行查找 */
		else
			low = mid + 1; /* 继续在后半区间进行查找 */
	}
	return 0; /* 顺序表中不存在待查元素 */
}

 

但是若加入数组分布不均匀,用插值查找未必是合适的选择。如{0,1,2,2000,2001….}。

 

 

二、斐波那契查找

 

斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=Fk-1;

 

1、算法思想

斐波那契查找的核心是: 
1)当 key=a[mid] 时,查找成功; 
2)当 key<a[mid] 时,新的查找范围是第 low 个到第 mid-1 个,此时范围个数为 F[k-1] - 1 个,即数组左边的长度,所以要在[low, F[k - 1] - 1] 范围内查找; 
3)当 key>a[mid] 时,新的查找范围是第 mid+1 个到第 high 个,此时范围个数为 F[k-2] - 1 个,即数组右边的长度,所以要在[F[k - 1] + 1 , high] 范围内查找。

   关于斐波那契查找, 如果要查找的记录在右侧,则左侧的数据都不用再判断了,不断反复进行下去,对处于当中的大部分数据,其工作效率要高一些。所以尽管斐波那契查找的时间复杂度也为O(logn),但就平均性能来说,斐波那契查找要优于折半查找。可惜如果是最坏的情况,比如这里key=1,那么始终都处于左侧在查找,则查找效率低于折半查找。

还有关键一点,折半查找是进行加法与除法运算的(mid=(low+high)/2),插值查找则进行更复杂的四则运算(mid = low + (high - low) * ((key - a[low]) / (a[high] - a[low]))),而斐波那契查找只进行最简单的加减法运算(mid = low + F[k-1] - 1),在海量数据的查找过程中,这种细微的差别可能会影响最终的效率。

 

 

 

三、分块查找

 

分块查找又称索引查找。它是一种介于顺序查找和二分查找之间的查找方法。在分块查找中,只要求索引表是有序的,对块内结点没有排序要求,因此特别适合结点动态变化的情况。

1、存储结构

分块查找是由“分块有序”的线性表和索引表两部分构成。

分块有序的线性表:假设要排序的表为 R[0...N-1],将表均匀分成 b 块,前 b-1 块中记录个数为 s=N/b,最后一块记录数小于等于 s;

每一块中的关键字不一定有序,但前一块中的最大关键字必须小于后一块中的最小关键字

注:这是使用分块查找的前提条件。

如上将表均匀分成b块后,抽取各块中的最大关键字起始位置构成一个索引表 IDX[0...b-1]。

由于表 R 是分块有序的,所以索引表是一个递增有序表

 

所示为一个索引顺序表。其中包括三个块,第一个块的起始地址为 0,块内最大关键字为 25;第二个块的起始地址为 5,块内最大关键字为 58,最小关键字为28,大于25;第三个块的起始地址为10,块内最大关键字为 88。

 

2、算法

分块查找算法有两个处理步骤:

(1) 首先查找索引表

因为分块查找表是“分块有序”的,所以我们可以通过索引表来锁定关键字所在的区间。

又因为索引表是递增有序的,所以查找索引可以使用顺序查找或二分查找。

(2) 然后在已确定的块中进行顺序查找

因为块中不一定是有序的,所以只能使用顺序查找。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值