插值搜索——本质和二分无异,是利用数据分布的规律来定查找点,其基本假设是数据分布均匀

简介:

2.2 插值查找

这是一种和二分比较相似的查找的算法, 不过不同的是, 对于分布比较均匀的较大的数组, 插值查找有时能够一次就搜索到位.. 
为什么能够这么快呢`? 看网上没有什么关于这种算法的描述, 我就来描述一下吧. 
首先要知道一点, 这种搜索方式只能够针对顺序表进行,, 再一个要理解顺序表中的一个特点, 在顺序表中查找是否存在一个值, 此时我可以对顺序表中的任意一个元素进行比较, 如果我要在A中寻找值为t的元素是否存在, 那么我用a[i]和t进行比较, (a[i]可以是顺序表中任意一个元素..), 如果a[i]==t的话, i就是t所在的位置, 如果a[i] > t,  那么说明t一定不在在a[i], a[i+1]....a[n-1], a[n]... 也就是说现在只需要对a[1]..a[i-1]进行搜索即可.. 
好好理解一下吧, 如果上面的理解不了, 那么插值查找就不好理解.. 

接下来我用low和high来保存该搜索的范围, 在刚开始low=0, hight=n-1. 设i是在low到high之间的相对位置.. 如: 若 i= 0, low = 0, 那么就该让t和a[i + low]比较, 即判断t是否和a[0]相等.. 
现在就是要确定i在哪里了.. 
假设顺序表的分布比较均匀, 那么有下面的方程: 
(t - a[low]) : (i + low) = (a[high] - a[low]) : (high - low) 
i = (t - a[low]) * (high - low) / (a[high] - a[low]) + low; 
差不多了吧... 
我的语言表达能力有限, 若还不大理解, 就看代码吧: 
C代码   收藏代码
  1. /* a是待搜索的顺序表,, size是a的长度, t 是待搜索的值 */  
  2. int search(int a[], int size, int t)  
  3. {  
  4.     int low = 0, high = size - 1;  
  5.     int pos;  
  6.     while(low <= high){  
  7.         pos = (t - a[low])/(a[high] - a[low])*(high - low) + low;  
  8.         if(a[pos] == t){  
  9.             return pos;  
  10.         }  
  11.         if(a[pos] > t){  
  12.             high = pos - 1;  
  13.         }else{  
  14.             low = pos + 1;  
  15.         }  
  16.     }  
  17.     return -1;  
  18. }  
 

2.3 斐波那契查找

原理:利用斐波那契数列的性质,黄金分割的原理来确定mid的位置。
代码如下:
[cpp]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. /*斐波那契 查找*/  
  2. int Fbonacci_Search(int *a, int n, int key)  
  3. {  
  4.     int low,high,mid,i,k;  
  5.     int F[] = {0,1,1,2,3,5,8,13,21,34};     //经典的斐波那契数列已经早就定义好,也可以递归自己求解。  
  6.     low = 1;  
  7.     high = n;  
  8.     k = 0;  
  9.     while(n > F[k] - 1)  //计算 n 位于斐波那契数列的位置  
  10.         k++;  
  11.     for(i=n; i<F[k] - 1; i++)    //将不满的数值补全  
  12.         a[i] = a[n];  
  13.     while(low <= high)  
  14.     {  
  15.         mid = low + F[k-1] - 1;         //利用斐波那契数列来找寻下一个要比较的关键字的位置  
  16.         if(key < a[mid])  
  17.         {  
  18.             high = mid - 1;  
  19.             k--;  
  20.         }  
  21.         else   
  22.         {  
  23.             if(key > a[mid])  
  24.             {  
  25.                 low = mid + 1;  
  26.                 k = k -2;  
  27.             }  
  28.             else  
  29.             {  
  30.                 if(mid <= n)  
  31.                     return mid;  
  32.                 else  
  33.                     return n;  
  34.             }  
  35.         }  
  36.     }  
  37. }  
 
总结:
折半查找进行加法与除法运算(mid = (low + high) / 2),插值查找进行复杂的四则运算( mid = low + (key - a[low] / (a[high] - a[low]) * (high - low)) ),二斐波那契查找只是运用简单家减法运算 (mid  = low + f[k-1] -1) ,在海量的数据查找过程中,这种席位的差别会影响最终的查找效率。三种有序表的查找本质上是分割点的选择不同,各有优劣,实际开发可根据数据的特点综合考虑再做决定。

 

转自:http://zqynux.iteye.com/blog/627133

http://blog.csdn.net/wangyunyun00/article/details/23464359












本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6591384.html,如需转载请自行联系原作者

相关文章
|
8月前
|
算法 测试技术 C++
【动态规划】【图论】【C++算法】1575统计所有可行路径
【动态规划】【图论】【C++算法】1575统计所有可行路径
|
8月前
|
存储 算法 程序员
【算法训练-回溯算法 二】【子集组合问题】子集、组合、子集II、组合总和
【算法训练-回溯算法 二】【子集组合问题】子集、组合、子集II、组合总和
72 0
|
7月前
|
人工智能 C++
组合+排列 以及伯努利装错信封问题思路
这段代码是C++实现的一个程序,用于计算从`n`个不同元素中选择`m`个进行排列的组合总数(排列问题)。用户输入`n`和`m`,程序通过循环和条件判断生成所有可能的排列,并输出排列的总数。核心逻辑是使用回溯法,当找到一个满足条件(不包含重复元素)的排列时,更新计数器并继续寻找下一个排列。
54 0
|
8月前
|
算法 测试技术 C#
【并集查找 图论 位运算】3108. 带权图里旅途的最小代价
【并集查找 图论 位运算】3108. 带权图里旅途的最小代价
|
7月前
|
机器学习/深度学习 存储 算法
技术笔记:LSH近似最近邻查找
技术笔记:LSH近似最近邻查找
64 0
|
8月前
|
算法 定位技术
插值、平稳假设、本征假设、变异函数、基台、块金、克里格、线性无偏最优…地学计算概念及公式推导
插值、平稳假设、本征假设、变异函数、基台、块金、克里格、线性无偏最优…地学计算概念及公式推导
184 2
|
算法 测试技术 C#
C++单调向量算法:132 模式解法三枚举1
C++单调向量算法:132 模式解法三枚举1
|
算法 C++
程序自动分析(并查集加离散化)
程序自动分析(并查集加离散化)
69 0
|
存储 数据可视化 数据挖掘
知识点丨重测序数据进行kinship亲缘关系分析、构建IBS矩阵的方法与介绍
知识点丨重测序数据进行kinship亲缘关系分析、构建IBS矩阵的方法与介绍
知识点丨重测序数据进行kinship亲缘关系分析、构建IBS矩阵的方法与介绍
|
存储 算法
基于链表和禁忌搜索启发式算法实现非一刀切二维矩形排样算法
基于链表和禁忌搜索启发式算法实现非一刀切二维矩形排样算法
110 0