折半查找与斐波那契查找算法实现

折半查找:先确定待查记录的所在的范围,然后逐步缩小范围直到找到或找不到该记录为止
在这里插入图片描述
代码实现:

/**
     * @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;
    }

猜你喜欢

转载自blog.csdn.net/qq_25744595/article/details/84564297