PHP有序表查找之插值查找算法示例


Posted in PHP onFebruary 10, 2018

本文实例讲述了PHP有序表查找之插值查找算法。分享给大家供大家参考,具体如下:

前言:

在前面我们介绍了二分查找,但是我们考虑一下,为什么一定要折半呢?而不是折四分之一或者更多?

打个比方,在英文词典里查找“apple”,你下意识里翻开词典是翻前面的书页还是后面的书页呢?如果再查“zoo”,你又会怎么查?显然你不会从词典中间开始查起,而是有一定目的地往前或往后翻。

同样,比如要在取值范围在 0 ~ 10000 之间的100个元素从小到大均匀分布的数组中查找5,我们自然而然地先考虑数组下标较小的开始查找。

以上的分析其实就是插值查找的思想,它是二分查找的改进。

基本思想:

根据要查找的关键字key与查找表中的最大最小记录的关键字比较后的查找方法,其核心就在于插值计算公式,我们先看折半查找的计算公式:

 PHP有序表查找之插值查找算法示例

而插值查找就是要将其中的 1/2进行改进,改成下面的计算方案:

 PHP有序表查找之插值查找算法示例

插值查找算法的核心就在于插值的计算公式:

$num - $arr[$lower]
—————————————
$arr[$high] - $arr[$lower]

代码:

<?php
//插值查找(前提是数组必须是有序数组) 事件复杂度 O(logn)
//但对于数组长度比较大,关键字分布又是比较均匀的来说,插值查找的效率比折半查找的效率高
$i = 0; //存储对比的次数
//@param 待查找数组
//@param 待搜索的数字
function insertsearch($arr,$num){
 $count = count($arr);
 $lower = 0;
 $high = $count - 1;
 global $i;
 while($lower <= $high){
  $i ++; //计数器
  if($arr[$lower] == $num){
   return $lower;
  }
  if($arr[$high] == $num){
   return $high;
  }
  // 折半查找 : $middle = intval(($lower + $high) / 2);
  $middle = intval($lower + ($num - $arr[$lower]) / ($arr[$high] - $arr[$lower]) * ($high - $lower)); 
  if($num < $arr[$middle]){
   $high = $middle - 1;
  }else if($num > $arr[$middle]){
   $lower = $middle + 1;
  }else{
   return $middle;
  }
 }
 return -1;
}
$arr = array(0,1,16,24,35,47,59,62,73,88,99);
$pos = insertsearch($arr,62);
print($pos);
echo "<br>";
echo $i;

总结:

从时间复杂度上来看,它也是 O(logn),但对于有序表比较长,而关键字分布有比较均匀的查找表来说,插值查找算法的平均性能比二分查找好的多。反之,数组中如果分布类似于{0,1,2,2000,2001,。。。999998,999999}这种极端不均匀的数据,用插值查找未必是很合适的选择。

我自己特别做了个例子:

$arr = array(0,1,2,2000,2001,2002,2003,2004,5555,69666,99999,100000);
echo "位置:".binsearch($arr,5555);
echo "<br>";
echo "比较次数:".$i;
$i = 0; //重置比较次数
echo "<br>";
echo "位置:".insertsearch($arr,5555);
echo "<br>";
echo "比较次数:".$i;

结果输出:

位置:8
比较次数:2
位置:8
比较次数:9

可以得到,对于极端不均匀的数据,插值查找效率比折半查找低。

PS:上面提到的binsearch()函数大家可以参考前面一篇 PHP有序表查找—-二分查找(折半)

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
随机广告显示(PHP函数)
Oct 09 PHP
php实现cc攻击防御和防止快速刷新页面示例
Feb 13 PHP
PHP中的日期加减方法示例
Aug 21 PHP
PHP反射机制用法实例
Aug 28 PHP
分享十款最出色的PHP安全开发库中文详细介绍
Mar 22 PHP
FastCGI 进程意外退出造成500错误
Jul 26 PHP
PHP基于GD库的图像处理方法小结
Sep 27 PHP
在IIS下安装PHP扩展的方法(超简单)
Apr 10 PHP
php实现的后台表格分页功能示例
Oct 23 PHP
php微信开发之关键词回复功能
Jun 13 PHP
Laravel5.1框架注册中间件的三种场景详解
Jul 09 PHP
php计数排序算法的实现代码(附四个实例代码)
Mar 31 PHP
PHP有序表查找之二分查找(折半查找)算法示例
Feb 09 #PHP
php在windows环境下获得cpu内存实时使用率(推荐)
Feb 08 #PHP
PHP基于redis计数器类定义与用法示例
Feb 08 #PHP
php处理抢购类功能的高并发请求
Feb 08 #PHP
php+redis实现商城秒杀功能
Nov 19 #PHP
php+redis消息队列实现抢购功能
Feb 08 #PHP
PHP多线程模拟实现秒杀抢单
Feb 07 #PHP
You might like
php数组函数序列之sort() 对数组的元素值进行升序排序
2011/11/02 PHP
如何使用PHP计算上一个月的今天
2013/05/23 PHP
JavaScript 中的日期和时间及表示标准介绍
2013/08/21 Javascript
js图片实时加载提供网页打开速度
2014/09/11 Javascript
浅析Node.js的Stream模块中的Readable对象
2015/07/29 Javascript
举例说明JavaScript中的实例对象与原型对象
2016/03/11 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
JavaScript DOM节点操作实例小结(新建,删除HTML元素)
2017/01/19 Javascript
vue-router路由简单案例介绍
2017/02/21 Javascript
Vue Ajax跨域请求实例详解
2017/06/20 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
require.js中的define函数详解
2017/07/10 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
JSONObject与JSONArray使用方法解析
2020/09/28 Javascript
[58:58]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第二场
2018/04/05 DOTA
python定时执行指定函数的方法
2015/05/27 Python
Python内置的HTTP协议服务器SimpleHTTPServer使用指南
2016/03/30 Python
Python简单实现enum功能的方法
2016/04/25 Python
Tensorflow的可视化工具Tensorboard的初步使用详解
2018/02/11 Python
使用python读取txt文件的内容,并删除重复的行数方法
2018/04/18 Python
python3 property装饰器实现原理与用法示例
2019/05/15 Python
python文件选择对话框的操作方法
2019/06/27 Python
tensorflow2.0保存和恢复模型3种方法
2020/02/03 Python
Python全面分析系统的时域特性和频率域特性
2020/02/26 Python
详解用python -m http.server搭一个简易的本地局域网
2020/09/24 Python
详解canvas.toDataURL()报错的解决方案全都在这了
2020/03/31 HTML / CSS
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
美国礼品卡商城: Gift Card Mall
2017/08/25 全球购物
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
公路绿化方案
2014/05/12 职场文书
2014年小学国庆节活动方案
2014/09/16 职场文书
python实现简易名片管理系统
2021/04/11 Python
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
吉利入股戴姆勒后smart“长大了”
2022/04/21 数码科技
Java中Dijkstra(迪杰斯特拉)算法
2022/05/20 Java/Android