当我们用到数组的时候,通常会用到通过键来查找值,这种比较简单,直接可以得出,但是当我们通过值来查找键时,就有些麻烦,有些语言提供了系统函数来实现这一功能,但是用别人的不如自己知道底层是怎么实现的。这里就介绍两种方法来实现通过值来获取键。以php语言为例。
顺序查找:数组可以是无序的,也可以是有序的,因为顺序查找是通过便利整个数组来确定键值。在php中可以通过foreach来进行遍历。在这里定义一个简单的索引数组。用于遍历寻找。
通过foreach进行遍历。通过查找帮助文档可以看到foreach的语言格式:
Foreach有两种格式,第一种只得到值,第二种得到键和值。显而易见,这里我们使用第二种方式。
通过foreach逐个得到数组的值,得到值之后和传入的值进行比较。如果相等,那么这个值就是我们想找的那个值,而这个键值是$key,返回key,也就是值得下标。
代码:
<?php
$arr = array(1,4,2,35,16,34,15);
function seek($arr,$value1){
foreach ($arr as $key => $value) {
if($value1 == $value){
return $key;
}
}
}
echo '15的索引值是:' . seek($arr,15);
?>
结果:
要知道,对于数组的下标,是从0开始计算的,所以15的在数组中是第七个数,下标是6;
二分查找:二分查找又称为折半查找,它比顺序查找的速度要快很多,平稳性好,但是缺点是查询的数组是一个有序的。
二分查找是把数组进行二分,先定义两个边界,一个是数组的开头start 0,一个是数组的结束end count($arr) - 1;将中间位置(mid = start + end)/2的值和与查找的值进行比较,如果两者相等,则查找成功,如果查找的值大于中间的值,则查找的值一定是在数组中间值得右边,这是只需要把start = mid + 1;如果查找的值小于中间的值,则查找的值一定是在数组中间值得左边,这时需要把end = mid - 1;循环查找,运行到最后,有两种情况:
1、一种是查到要查的值
2、第二种是查找不到,并且start > end;
上面的话转化成图形也就是下面这个图,但是当数组的mid是小数是,可以使用round()函数进行四舍五入。
能找到结果的示意图:
Start > end的情况:
代码实现:
<?php
$arr = array(1,2,4,6,7,12,15);
function binarySearch(&$arr,$value,$start,$end){
if($start > $end){
echo '没有找到';
return;
}
$mid = round(($start + $end) / 2);
if($arr[$mid] == $value){
return $mid;
}else if($arr[$mid] > $value){
return erFen($arr,$value,$start,$mid - 1);
}else{
return erFen($arr,$value,$mid + 1,$end);
}
}
echo binarySearch($arr,13,0,count($arr) - 1);
这个二分查找用到递归。递归简单来说就是自己调用自己,他有两个条件,
1、必须有一些基准条件,它无需递归就能算出结果。
2、对于需要递归进行运算的,每一次递归调用都必须要向基准条件推进。
在上面的代码中,
if($start > $end){
echo '没有找到';
return;
}
if($arr[$mid] == $value){
return $mid;
}
都可以看作是基准条件。通过递归不断的进行二分,从而得到结果。
总结:
- 顺序查找查找效率低下,但是数组可以使无序的
- 二分查找虽然要求数组是有序的,但是查询效率高。
- 至于使用哪种,就要看有什么要求。