๐ ํผ๋ณด๋์น ์์ด์ ๋ํ ์ค๋ช
์ ๋ ฌ ๋ฐฐ์ด์์ ๋์ ๊ฐ์ ์์น๋ฅผ ์ฐพ๋ ์ผ๋ฐ์ ์ธ ์๊ณ ๋ฆฌ์ฆ
๋ถํ ์ ๋ณต ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ ๋ ฌ๋ ๋ฐฐ์ด์ ๊ฒ์ํ๋ ๋ฐฉ๋ฒ
๐ Fibonacci Search๋?
์ด์ง ๊ฒ์๊ณผ ๋น์ทํ ์๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง๋ง, ๊ฒ์ ์์น๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ค๊ฐ ๊ฐ(mid) ๋์ , ํผ๋ณด๋์น ์์ด์์์ ๊ฐ์ ์ฌ์ฉ.
์ด์ง ๊ฒ์๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ฒ์ ๋ฒ์๋ฅผ ๋ฐ๋ณตํด์ ์ ๋ฐ์ผ๋ก ์ค์ฌ๊ฐ๋ฉด์ ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ ์ฐพ์.
ํด๋น ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๋ O(log3(n))์ด๊ณ , ๊ณต๊ฐ ๋ณต์ก๋๋ O(1)์ด๋ค.
๐ Fibonacci Search ์๋ฆฌ
๋จผ์ , ์ฃผ์ด์ง ๋ฐฐ์ด์์ ๊ฒ์ ๋ฒ์๋ฅผ ๊ฒฐ์ .
์ด๊ธฐ ๊ฒ์ ๋ฒ์๋ ์ ์ฒด ๋ฐฐ์ด์ด๋ค.
์ด์ง ๊ฒ์๊ณผ ๋ฌ๋ฆฌ, ๊ฒ์ ์์น(mid)๋ ํผ๋ณด๋์น ์์ด์์์ ๊ฐ์ ์ฌ์ฉ.
==> ๊ฒ์ ๋ฒ์๋ฅผ ํผ๋ณด๋์น ์์ด์์์ ๊ฐ์ ์ฌ์ฉํ์ฌ ๊ณ์ํด์ ๋๋ ๋๊ฐ๋ฉด์ ๊ฒ์.
๊ฒ์ ๋ฒ์ ๋ด์์ ์ฐพ๊ณ ์ ํ๋ ๊ฐ(key ๊ฐ)๊ณผ mid์ ์์นํ ๊ฐ์ ๋น๊ต
- key < mid:
 
๊ฒ์ ๋ฒ์๋ฅผ ์์ชฝ ๋ถ๋ถ(์์ ์ชฝ)์ผ๋ก ์ด๋ํฉ๋๋ค. ์ด ๋, mid์ ์์น๋ ์์ชฝ ๋ถ๋ถ์์ ๋ ๋ฒ์งธ ํผ๋ณด๋์น ์์ด ๊ฐ์ ์์น์ ์์ต๋๋ค- key > mid:
 
๊ฒ์ ๋ฒ์๋ฅผ ๋ค์ชฝ ๋ถ๋ถ(ํฐ ์ชฝ)์ผ๋ก ์ด๋ํฉ๋๋ค. ์ด ๋, mid์ ์์น๋ ๋ค์ชฝ ๋ถ๋ถ์์ ์ฒซ ๋ฒ์งธ ํผ๋ณด๋์น ์์ด ๊ฐ์ ์์น์ ์์ต๋๋ค.- key == mid:
 
๊ฒ์ ์ข ๋ฃ
๐ป ์ฝ๋
๐ฝ ์ฃผ์ด์ง ๋ฐฐ์ด(array)์ ๊ธธ์ด๋ณด๋ค ์์ ํผ๋ณด๋์น ์์ด ๊ฐ์ ์ฐพ์
package com.thealgorithms.searches;
import com.thealgorithms.devutils.searches.SearchAlgorithm;
/*
 *  Fibonacci Search is a popular algorithm which finds the position of a target value in
 *  a sorted array
 * -> ์ ๋ ฌ ๋ฐฐ์ด์์ ๋์ ๊ฐ์ ์์น๋ฅผ ์ฐพ๋ ์ผ๋ฐ์ ์ธ ์๊ณ ๋ฆฌ์ฆ.
 *
 *  The time complexity for this search algorithm is O(log3(n))
 * -> ์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๋ O(log3(n))
 *  The space complexity for this search algorithm is O(1)
 * -> ์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๊ฐ ๋ณต์ก๋๋ O(1)
 *  @author Kanakalatha Vemuru (https://github.com/KanakalathaVemuru)
 */
public class FibonacciSearch implements SearchAlgorithm {
    /**
     * @param array is a sorted array where the element has to be searched
     * -> ์์๋ฅผ ๊ฒ์ํด์ผ ํ๋ ์ ๋ ฌ๋ ๋ฐฐ์ด
     * @param key is an element whose position has to be found
     * -> ์์น๋ฅผ ์ฐพ์์ผ ํ๋ ์์
     * @param <T> is any comparable type
     * @return index of the element
     */
    @Override
    public <T extends Comparable<T>> int find(T[] array, T key) {
        int fibMinus1 = 1; // F_{n-1}
        int fibMinus2 = 0; // F{n-2}
        int fibNumber = fibMinus1 + fibMinus2; // F_{n}=F_{n-1}+F{n-2}
        int n = array.length; // ์ด๊ธฐ ๊ฒ์ ๋ฒ์ = ์ ์ฒด ๋ฐฐ์ด
        // ํผ๋ณด๋์น ์์ด ๊ฐ ์ฐพ์. ๊ฐ ๊ฐ๋ค์ ์์ฐจ์  ์
๋ฐ์ดํธ
        while (fibNumber < n) {
            fibMinus2 = fibMinus1; // 2 =1
            System.out.print("F{n-2} ํ์ธ: " + fibMinus2 + "  ");
            fibMinus1 = fibNumber; // 1 = 1
            System.out.print("F{n-1} ํ์ธ: " + fibMinus1 + "  ");
            fibNumber = fibMinus2 + fibMinus1;
            System.out.print("ํผ๋ณด๋์น ์์ด ์งํ:" + fibNumber + "  ");
            
            System.out.println();
        } // -> ํผ๋ณด๋์น ์์ด ๋ฐ๋ณต.
        System.out.println("fibNumber ์ต์ข
 ๋๋ฆผ:" + fibNumber);
        
๐ข ์ถ๋ ฅ ๊ฒฐ๊ณผ

โ
 offset ์ ์ธํ ์ด์ .
offset ๋ณ์๋ ๊ฒ์ ๋ฒ์์ ์์ ์์น๋ก ๊ฒ์ ๋์ ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ์์๋ถํฐ ํ์ฌ ๊ฒ์ ๋ฒ์์ ์์ ์์น๊น์ง์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ํ๋.
        int offset = -1;
        
        // ์ฐพ๊ณ ์ ํ๋ ๊ฐ(key)๊ณผ mid์ ์์นํ ๊ฐ(array[i])์ ๋น๊ตํ๋ฉด์ ๊ฒ์ ์ํ
        while (fibNumber > 1) {
            System.out.println("fibMinus2์ ๊ฐ:" + fibMinus2);
            System.out.println("offset + fibMinus2์ ๊ฐ: " + (offset + fibMinus2));
            int i = Math.min(offset + fibMinus2, n - 1);
            System.out.println("i์ ๊ฐ:" + i);
            System.out.println("array[i].compareTo(key) ํ์ธ:" +  array[i].compareTo(key));
            
            /*
             * compareTo:
             * ํ ๊ฐ์ฒด: this, ํ๋ผ๋ฉํ: obj
             * 1. this < obj ==> ์์๋ฆฌํด
             * 2. this == obj ==> 0 ๋ฆฌํด
             * 3. this > obj ==> ์์ ๋ฆฌํด.
             */
             
            if (array[i].compareTo(key) < 0) {
                fibNumber = fibMinus1;
                fibMinus1 = fibMinus2;
                fibMinus2 = fibNumber - fibMinus1;
                offset = i;
                System.out.println(
                        "์์ ๊ฒฐ๊ณผ ์: " + " fibNumber: " +
                                fibNumber +
                        ". fibMinus1 " +
                        fibMinus1 +
                        " . fibMinus2 " +
                        fibMinus2 +
                        " + offset " +
                        offset
                    );
                System.out.println();
            } else if (array[i].compareTo(key) > 0) {
                fibNumber = fibMinus2;
                fibMinus1 = fibMinus1 - fibMinus2;
                fibMinus2 = fibNumber - fibMinus1;
                System.out.println(
                        "์์ ๊ฒฐ๊ณผ ์: " + " fibNumber: " +
                                fibNumber +
                        ". fibMinus1 " +
                        fibMinus1 +
                        " . fibMinus2 " +
                        fibMinus2 
                    );
            } else {
                return i; // this == obj ==> 0 ๋ฆฌํด
            }
        }
        if (fibMinus1 == 1 && array[offset + 1] == key) {
            System.out.println("๋ค์ด์์ด?");
            return offset + 1;
        }
        return -1;
    }
๐ข ์ถ๋ ฅ ๊ฒฐ๊ณผ

    // Driver Program
    public static void main(String[] args) {
        Integer[] integers = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
        int size = integers.length;
        Integer shouldBeFound = 128;
        FibonacciSearch fsearch = new FibonacciSearch();
        int atIndex = fsearch.find(integers, shouldBeFound);
        System.out.println(
            "Should be found: " +
            shouldBeFound +
            ". Found " +
            integers[atIndex] +
            " at index " +
            atIndex +
            ". An array length " +
            size
        );
    }
}
๐ข ์ถ๋ ฅ ๊ฒฐ๊ณผ

์ถ์ฒ:
<https://pgh268400.tistory.com/70
https://ko.wikipedia.org/wiki/%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98_%EC%88%98>
https://en.wikipedia.org/wiki/Fibonacci_search_technique