基础算法-查找:插值查找

算法描述

先来看一个实际问题:
我们在一本英汉字典中寻找单词“worst”,我们决不会仿照对半查找(或Fibonacci查找)那样,先查找字典中间的元素,然后查找字典四分之三处的元素等等. 事实上,我们是在所期望的地址(在字典的很靠后的地方)附近开始查找的,我们称这样的查找为插值查找。

可见,插值查找不同于前面讨论的几种查找算法,前面介绍的查找算法是基于严格比较的,即假定我们对线性表中元素的分布一无所知(或称没有启发式信息). 然而实际中,很多查找问题所涉及的表满足某些统计的特点。

插值查找在实际使用时,一般要满足两个假设条件:

(1)每一次对数据的访问与通常的指令相比,费用都是相当昂贵的。例如,待查找的表一定是在磁盘而非内存中,因而每一次比较都要进行磁盘访问。

(2)数据不仅是已被排好序的,而且呈现均匀分布特征。

伪代码

insertValue_Search(R,n,element)
//实现给定有序均匀分布数组R中元素element的查找
//输入:数组R,数组长度n,待查找元素的位置
//有无待查找的元素
from←0 ,to←n-1                    //初始化起止位置
while(from <= to)
	middle ← from+(element-R[from])/(R[to]-R[from])*(to-from+0.5)//采用插值方法计算
	if R[mid]=element  return mid
	if R[mid]>element  to←mid-1
	if R[mid]<element  from←mid+1
return -1

具体实现

/*
*	功能:该函数用来实现插值查找算法
*	输入:查找数组search_table,数组长度n,查找元素element
*	输出:返回元素的位置
*/
int insertValue_Search(int search_table[], int n, int element)
{
	int low = 0;
	int high = n - 1;

	while(low <= high)
	{
		int mid = (int)(low + (element-search_table[low])/(search_table[high]-search_table[low])*(high-low));
		if(search_table[mid] == element)
		{
			return mid;
		}
		else if(search_table[mid] > element)
		{
			high = mid - 1;
		}
		else
		{
			low = mid + 1;
		}
	}//while

	return -1;
}

  从时间复杂度上来说,插值查找的时间复杂度也是O(logn),但对于表长较大,而关键字分布又比较均匀的查找来说,插值算法的平均性能比折半查找要好得多。但是,如果数组中的分布类似[0,1,2,2000,2001,......,99998,99999]这种极端不均匀的数据,用插值查找未必是合适的算法。

所以说,没有最好的算法,只有针对具体情况的最合适的算法。

时间: 2024-08-04 20:32:05

基础算法-查找:插值查找的相关文章

基础算法介绍 —— 二分查找算法

不知不觉在目前的公司待满3年了,打算回家找份工作.面试中被问到关于算法的题目:有哪些常见的查找算法?下来就把我所掌握的查找算法分享给大家,本文主要介绍二分查找算法. 算法定义(摘自百度):二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果

基础算法之二分查找

二分查找 利用分治法,逐渐苏小查找范围,适用于有序数组. 时间复杂度是O(log2N). PS:二分查找算法的判定过程实际上可以借助一棵平衡二叉树来描述,中间位置的关键字可以看成二叉树的根节点. C++代码如下: 1 #include <iostream> 2 using namespace std; 3 template<class DataType> int binSearch(DataType key[],int n,DataType k) 4 { 5 int low=0,h

基础算法之二分查找总结

本博客是我在做题和看书遇到各种情况的总结. 参考了书,邓俊辉老师编写的<数据结构(C++语言版)(第3版)>,同时还有网友的总结(以下会给出相应的链接).  一.查找等于目标元素的位置(若是多个,只要求找到即可) 1 /二分查找的主体 2 int binarySearch(int A[], int n, int target) 3 { 4 int lo = 0, hi = n; //n为数组的A元素的个数 5 6 while (lo < hi) 7 { 8 int mid = lo +

数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找

今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找.本篇博客会给出相应查找算法的示意图以及相关代码,并且给出相应的测试用例.当然本篇博客依然会使用面向对象语言Swift来实现相应的Demo,并且会在github上进行相关Demo的分享. 查找在生活中是比较常见的,本篇博客所涉及的这几种查找都是基于线性结构的查找.也就是说我们的查找表是一个线性表,我

算法:二分查找(基础)

二分查找是一个基础的算法,也是面试中常考的一个知识点. 基础二分查找 二分查找就是将查找的键和子数组的中间键做比较,如果被查找的键小于中间键,就在左子数组继续查找:如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素. /** * 二分查找,找到该值在数组中的下标,否则为-1 */ static int binarySerach(int[] array, int key) { int left = 0; // 左边开始位置的下标 int right = array.length - 1;

常见的查找算法(三):插值查找

插值搜索法(Interpolation search)是利用插值公式来计算猜测搜索键值的位置.搜索方式与二分搜索相同 插值公式: 插值 = (设算数 -­ 最小数) / (最大数 -­ 最小数): [2] 搜索键值 = left + parseInt( ( key - data[ left ] ) / ( data[ right ] - data[ left ] ) ) * ( right - left ) ) 插值搜索之算法与二分搜索算法几乎完全相同,差别在: 二分搜索法:猜测键值在中间位置(

基础算法-查找:折半查找

折半查找 又称为二分查找.这种查找方法要求查找表的数据是线性结构保存,并且还要求查找表中的数据是按关键字由小到大有序排列. 折半查找(二分查找)是一种简单而又高效的查找算法,其查找长度至多为㏒2n+1(判定树的深度),平均查找长度为㏒2(n+1)-1,效率比顺序查找要高,但折半查找只能适用于顺序存储有序表(如对线性链表就无法有效地进行折半查找). 经典非递归算法实现 int Binary_Search(int search_table[], int key, int low ,int high)

数据结构之--插值查找

数据结构之--插值查找 定义:插值查找就是把要查找的关键字key与查找表中最大和最小记录的关键字比较后的查找方法,其核心就在于插值的计算公式(key-a[low])/(a[high]-a[low]) 图解: 时间复杂度:只是把折半的算法由mid=(low+high)/2变为了(mid=low+(high-low)*(key-a[low])/(a[high]-a[low])),所以时间复杂度还是为与普通折半查找一样为:O(logn). #include<stdio.h> int Binary_S

二分算法入门——二分查找

二分查找,无论是从名字还是理论都十分简单一个算法,其博大精深,简直恐怖.Jon Bentley:90%以上的程序员无法正确无误的写出二分查找代码. 别人不知道,反正我早上是写了好久,这个查找算法,将查找的复杂度从 o( n ) 降到了 o( logn ) ,当之无愧的的好算法,更是许多高级算法的优化策略之一. 二分查找之基本思路 虽然二分查找是一个很吊的算法,但是跟很多算法一样,需要使用的基础条件——序列有序! 先假设一个单调非增序列:1 2 3 4 5 6 ,求找到3的位置,地球人都会马上这么