折半查找:先确定待查记录的所在的范围,然后逐步缩小范围直到找到或找不到该记录为止
代码实现:
/**
* @name 线性表查找
* @use 从线性表中查找一个元素
* @param list 线性表
* @param aim 目标元素
* @type ORDER_01|ORDER_02|NOT_ORDER 线性表为升序序|线性表为降序|线性表为无序
* @return index 目标元素的下标
*/
public static function linerFind($list, $aim, $type) {
if ($type == self::$NOT_ORDER) {
foreach ($list as $key => $value) {
if ($aim == $value) {
return $key;
}
}
return false;
}
$low = 0;
$height = count($list) - 1;
if ($type == self::$ORDER_UP) {
while ($height >= $low) {
$index = floor(($height + $low) / 2);
if ($aim == $list[$index]) {
return $index;
}
if ($aim > $list[$index]) {
$low = $index + 1;
} else {
$height = $index - 1;
}
}
return false;
}
if ($type == self::$ORDER_DESC) {
while ($height >= $low) {
$index = floor(($height + $low) / 2);
if ($aim == $list[$index]) {
return $index;
}
if ($aim > $list[$index]) {
$height = $index - 1;
} else {
$low = $index + 1;
}
}
return false;
}
}
斐波那契查找:按照斐波那契数列来确定分割点,假设表中记录个数比某个斐波那契数小于1,即n=Fu-1,则查找分割点为斐波那契数F(u-1)的值,如此将表中记录分为了n1和n2两部分,其中n1中元素数目等于斐波那契数F(u-1) - 1 的值,而n2中元素的个数为斐波那契数F(u-2) - 1的值。如果给定值等于n则查找成功,如果给定值大于n则在n2中进行斐波那契查找,如果跟定值小于n则在n1中进行斐波那契查找。
代码实现:
/**
* @name 斐波那契查找
* @use 使用斐波那契查找法从有序数组中找目标元素
* @param arr 数组
* @param aim 目标元素
* @return index|false 目标元素下标|未找到
*/
public static function findFibonacci($arr, $aim)
{
$num = count($arr) - 1;
$a = $b = 1;
$fibonacci = array($a,$b);
while ($b < $num) {
$temp = $a;
$a = $b;
$b = $temp + $a;
$fibonacci[] = $b;
}
$low = 0;
$height = $num;
$count = 0;
while ($low <= $height) {
$count++;
$num = $height - $low + 1;
$index = $low;
foreach ($fibonacci as $key => $value) {
if ($num == 1) {
$index = $low;
break;
}
if ($value >= $num) {
$index = $fibonacci[$key - 1] + $low;
break;
}
}
if ($aim == $arr[$index]) {
return $index;
} else if ($aim > $arr[$index]) {
$low = $index + 1;
} else {
$height = $index - 1;
}
}
return false;
}