# 이진검색

written by sohyeon, hyemin πŸ’‘


# 1. μ΄μ§„κ²€μƒ‰μ΄λž€?

μš”μ†Œκ°€ μ˜€λ¦„μ°¨μˆœ λ˜λŠ” λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬λœ λ°°μ—΄μ—μ„œ κ²€μƒ‰ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

μ•„λž˜λŠ” n개의 μš”μ†Œκ°€ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ λŠ˜μ–΄μ„  λ°°μ—΄ aμ—μ„œ ν‚€λ₯Ό 이진 κ²€μƒ‰μœΌλ‘œ κ²€μƒ‰ν•˜λŠ” 과정을 ν‘œν˜„ν•œ 것이닀.
pl은 검색 λ²”μœ„μ˜ 맨 μ•ž 인덱슀, pr은 맨끝 인덱슀, pcλŠ” 쀑앙 인덱슀라고 μ§€μ •ν•œλ‹€.

검색을 μ‹œμž‘ν•  λ•Œ pl은 0, pr은 n-1, pcλŠ” (n-1)/2둜 μ΄ˆκΈ°ν™”μ΄λ‹€.

이진검색을 ν•œ 단계씩 진행할 λ•Œλ§ˆλ‹€ 검색 λ²”μœ„κ°€ (거의)반으둜 μ’ν˜€μ§„λ‹€.
λ˜ν•œ κ²€μ‚¬ν•œ μš”μ†Œλ₯Ό ν•˜λ‚˜μ”© μ œμ™Έμ‹œν‚€λŠ” μ„ ν˜• κ²€μƒ‰κ³ΌλŠ” λ‹€λ₯΄κ²Œ
이진 검색은 검색 μš”μ†Œκ°€ ν•΄λ‹Ή λ‹¨κ³„μ—μ„œ λ‹€μŒμ— 검색할 λ²”μœ„μ˜ 쀑간 μ§€μ μœΌλ‘œ λ‹¨μˆ¨μ— μ΄λ™ν•˜λŠ” νŠΉμ§•μ„ κ°–λŠ”λ‹€.

μœ„μ˜ 그림은 μ„±κ³΅ν–ˆμ„ λ•Œμ˜ μ˜ˆμ‹œμ΄λ‹€.
λ§ˆμ§€λ§‰ κ³Όμ •μ²˜λŸΌ a[pc]와 keyλ₯Ό λΉ„κ΅ν•˜μ—¬ κ°™μœΌλ©΄ 검색에 μ„±κ³΅ν•˜μ—¬ 과정이 λλ‚œλ‹€.
ν•˜μ§€λ§Œ μ›ν•˜λŠ” 값을 찾지λͺ»ν•˜λ©΄ 같은 λ°©λ²•μœΌλ‘œ 검색 λ²”μœ„λ₯Ό μ’ν˜€κ°€λ©° λ°˜λ³΅ν•˜κ²Œ λœλ‹€.

이 λ•Œ, 두가지 κ²½μš°μ— 따라 λ‹€λ₯΄κ²Œ 검색 λ²”μœ„λ₯Ό 쒁히게 λœλ‹€.

  1. a[pc]<keyμΌλ•Œ

    a[pl]~a[pc]λŠ” key보닀 μž‘μ€ 것이 λΆ„λͺ…ν•˜λ―€λ‘œ κ²€μƒ‰λŒ€μƒμ—μ„œ μ œμ™Έν•œλ‹€.
    검색 λ²”μœ„λŠ” a[pc]보닀 λ’€μͺ½μ˜ a[pc+1]~a[pr]둜 μ’νžŒλ‹€.
    그런 λ‹€μŒ pl의 값을 pc+1둜 μ—…λ°μ΄νŠΈ ν•œλ‹€.

  2. a[pc]>keyμΌλ•Œ

    a[pc]~a[pr]은 key보닀 큰 것이 λΆ„λͺ…ν•˜λ―€λ‘œ κ²€μƒ‰λŒ€μƒμ—μ„œ μ œμ™Έν•œλ‹€.
    검색 λ²”μœ„λŠ” a[pc]보닀 μ•žμͺ½ a[pl]~a[pc-1]둜 μ’νžŒλ‹€.
    그런 λ‹€μŒ pr의 값을 pc-1둜 μ—…λ°μ΄νŠΈ ν•œλ‹€.

# 이진 κ²€μƒ‰μ˜ μ’…λ£Œ 쑰건

  • a[pc]와 keyκ°€ μΌμΉ˜ν•˜λŠ” 경우
  • 검색 λ²”μœ„κ°€ 더 이상 μ—†λŠ” 경우

# μ˜ˆμ‹œ μ½”λ“œ

class BinSearch{
    //μš”μ†Ÿμˆ˜κ°€ n인 λ°°μ—΄ aμ—μ„œ key와 같은 μš”μ†Œλ₯Ό 이진 검색
    static int binSearch(int[] a, int n, int key){
        int pl = 0;
        int pr = n-1;
        do{
            int pc = (pl+pr)/2; // 쀑앙 인덱슀 μš”μ†Œ
            if(a[pc]==key)
                return pc;      // 검색 성곡
            else if(a[pc]<key)
                pl = pc+1;      // 검색 λ²”μœ„λ₯Ό λ’€μͺ½ 절반으둜 쒁힘
            else
                pr = pc-1;      // 검색 λ²”μœ„λ₯Ό μ•žμͺ½ 절반으둜 쒁힘
        } while (pl<=pr);
        return -1
    }

    public static void main(Stirng[] args){
        Scanner stdIn = new Scanner(System.in);

        System.out.print("μš”μ†Ÿμˆ˜: ");
        int num = stdIn.nextInt();
        int[] x = new int[num];

        System.out.println("μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μž…λ ₯ν•˜μ„Έμš”.");

        System.out.print("x[0]: ");
        x[0] = stdIn.nextInt();

        for(int i=0; i<num; i++){
            do{
                System.out.print("x["+i+"]:");
                x[i] = stdIn.nextInt();
            } while (x[i]<x[i-1]);
        }

        System.out.print("검색할 κ°’:");
        int ky = stdIn.nextInt();

        int idx = binSearch(x, num, ky);    // λ°°μ—΄ xμ—μ„œ ν‚€ 값이 ky인 μš”μ†Œλ₯Ό 검색

        if(idx==-1)
            System.out.println("κ·Έ κ°’μ˜ μš”μ†Œκ°€ μ—†μŠ΅λ‹ˆλ‹€.");
        else
            System.out.println(ky+"은(λŠ”) x["+idx+"]에 μžˆμŠ΅λ‹ˆλ‹€.");
    }
}

μœ„μ˜ μ˜ˆμ‹œ μ½”λ“œμ—μ„œλŠ” μžλ°”λ‘œ 직접 이진탐색을 κ΅¬ν˜„ν•΄ λ³΄μ•˜λ‹€.

ν•˜μ§€λ§Œ JavaλŠ” λ°°μ—΄μ—μ„œ 이진 검색을 ν•˜λŠ” λ©”μ„œλ“œλ₯Ό ν‘œμ€€ 라이브러리둜 μ œκ³΅ν•œλ‹€.
java.util.Arrays 클래슀의 binarySearch λ©”μ„œλ“œμ΄λ‹€.
μžλ£Œν˜•μ— 따라 9가지 λ°©λ²•μœΌλ‘œ μ˜€λ²„λ‘œλ”© λ˜μ–΄ μžˆλ‹€.
Java API κ³΅μ‹λ¬Έμ„œλ₯Ό 톡해 λ©”μ„œλ“œμ— λŒ€ν•œ μ„€λͺ…을 확인할 수 μžˆλ‹€.

# Java binarysearch λ©”μ„œλ“œμ˜ μž₯점

  • 이진 검색 λ©”μ„œλ“œλ₯Ό 직접 μ½”λ”©ν•  ν•„μš”κ°€ μ—†λ‹€.

  • λͺ¨λ“  μžλ£Œν˜• λ°°μ—΄μ—μ„œ 검색할 수 μžˆλ‹€.

Last Updated: 12/5/2020, 11:36:44 AM