查找算法之二分查找(插值查找)
对半查找和斐波那契查找对于元素关键字的整体分布没有要求,可以均匀分布,也可以不均匀分布。对于关键字分布不均匀且没有规律的情况,确实很难找到更好的方法提高算法的查找效率;但是如果查找序列的关键字分布均与,那么是可以利用这种均匀性来提高算法效率的,例如使用插值查找。
在关键字值分布均匀的情况下,使用插值查找可以提高效率,那插值查找的原理是怎样的?下面举一个例子:
关键字 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |
---|---|---|---|---|---|---|---|---|---|---|
元素值 | 11 | 12 | 15 | 13 | 14 | 16 | 18 | 20 | 25 | 24 |
这组序列的关键字在2~20之间均匀分布,这时如果要查找关键字为18的元素值,是不是可以直接计算出关键字为18的元素的存储位置呢?
用数组来存储这组序列:
数组下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
关键字 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |
元素值 | 11 | 12 | 15 | 13 | 14 | 16 | 18 | 20 | 25 | 24 |
用 (18-2)/(20-2) 可以计算出关键字18在整个关键字序列中的相对位置,是在关键字序列的 位置,然后用这个相对位置乘上整个序列长度,即(18-2)/(20-2)*(9-0),就可以转换为该关键字在子表中的相对位置,当然这个式子严格意义上并不完整,完整的应该是 (18-2)/(20-2)*(9-0)+0。
所以在插值查找算法中的的计算公式为:
这是个极端例子,关键字是完全均匀分布的,所以只需计算一次值就可以查找到对应元素;但是这种情况极为少见,更多的是相对均匀的情况,一次计算并不能解决,这时仍然要采用二分查找的策略,将查找范围一步步划分为更小的子表。
从这个例子来看,在关键字值分布均匀的情况下,插值查找的平均性能优于对半查找;但是如果关键字值分布非常不均匀的情况下,插值查找的平均性能会差很多。
本篇完 ????