1. 程式人生 > >折半查詢與斐波那契查詢演算法實現

折半查詢與斐波那契查詢演算法實現

折半查詢:先確定待查記錄的所在的範圍,然後逐步縮小範圍直到找到或找不到該記錄為止
在這裡插入圖片描述
程式碼實現:

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