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项目开发中最常用的自定义函数整理
Dec 02 PHP
19个超实用的PHP代码片段
Mar 14 PHP
php setcookie函数的参数说明及其用法
Apr 20 PHP
PHP中的类型提示(type hinting)功能介绍
Jul 01 PHP
深入理解PHP内核(一)
Nov 10 PHP
PHP+ajax分页实例简析
Dec 07 PHP
php opendir()列出目录下所有文件的实例代码
Oct 02 PHP
PHP使用DOM和simplexml读取xml文档的方法示例
Feb 08 PHP
php UNIX时间戳用法详解
Feb 16 PHP
thinkphp5框架实现数据库读取的数据转换成json格式示例
Oct 10 PHP
php文件上传原理与实现方法详解
Dec 20 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 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命名空间学习详解
2014/02/27 PHP
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
Javascript中call与apply的学习笔记
2014/09/22 Javascript
NodeJS学习笔记之Connect中间件模块(二)
2015/01/27 NodeJs
jQuery内容过滤选择器用法分析
2015/02/10 Javascript
被遗忘的javascript的slice() 方法
2015/04/20 Javascript
jquery实现的判断倒计时是否结束代码
2016/02/05 Javascript
javascript弹出带文字信息的提示框效果
2016/07/19 Javascript
使用plupload自定义参数实现多文件上传
2016/07/19 Javascript
JS查找字符串中出现次数最多的字符
2016/09/05 Javascript
Bootstrap表格制作代码
2017/03/17 Javascript
浅谈Node.js之异步流控制
2017/10/25 Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
2018/05/01 Javascript
微信小程序中为什么使用var that=this
2019/08/27 Javascript
解决layui 三级联动下拉框更新时回显的问题
2019/09/03 Javascript
layer的prompt弹出框,点击回车,触发确定事件的方法
2019/09/06 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
layui 图片上传+表单提交+ Spring MVC的实例
2019/09/21 Javascript
jQuery使用ajax传递json对象到服务端及contentType的用法示例
2020/03/12 jQuery
JavaScript实现留言板案例
2020/03/17 Javascript
Vue+ElementUI 中级联选择器Bug问题的解决
2020/07/31 Javascript
Javascript数组及类数组相关原理详解
2020/10/29 Javascript
Python中的XML库4Suite Server的介绍
2015/04/14 Python
Python中的lstrip()方法使用简介
2015/05/19 Python
Python实现批量将word转html并将html内容发布至网站的方法
2015/07/14 Python
Python实现的基数排序算法原理与用法实例分析
2017/11/23 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
2020/06/01 Python
python map比for循环快在哪
2020/09/21 Python
《雾凇》教学反思
2014/02/17 职场文书
任命书格式
2014/06/05 职场文书
教师节倡议书
2014/08/30 职场文书
关于运动会的广播稿
2014/09/22 职场文书
2015年大学宣传部工作总结
2015/05/26 职场文书
SpringDataJPA实体类关系映射配置方式
2021/12/06 Java/Android
MySQL分区以及建索引的方法总结
2022/04/13 MySQL
MySql如何将查询的出来的字段进行转换
2022/06/14 MySQL