𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[μ•Œκ³ λ¦¬μ¦˜] 이뢄 탐색(Binary Search) λ³Έλ¬Έ

μ•Œκ³ λ¦¬μ¦˜

[μ•Œκ³ λ¦¬μ¦˜] 이뢄 탐색(Binary Search)

.23 2021. 8. 8. 00:16

1. 이뢄 탐색 ; Binary Search

1.1 κ°œλ…

λ²”μœ„λ₯Ό 점점 μ’ν˜€κ°€λ©° 탐색을 ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ, 이진 탐색이라고도 ν•œλ‹€. ν•˜λ‚˜μ”© μ°ΎλŠ” 것이 μ•„λ‹Œ left와 right μ–‘μͺ½μ—μ„œ 탐색을 ν•˜κΈ° λ•Œλ¬Έμ— 일반 탐색에 λΉ„ν•΄ 속도가 λΉ λ₯΄λ‹€. μ‹œκ°„λ³΅μž‘λ„λŠ” 일반 탐색이 O(n), 이뢄 탐색이 O(log n)이닀.

μ•Œκ³ λ¦¬μ¦˜μ΄ μž‘λ™ν•˜λŠ” 방식은 λ‹€μŒκ³Ό κ°™λ‹€.

 

  1. 미리 μ •λ ¬λœ λ°°μ—΄μ—μ„œ, 정해놓은 인덱슀 μœ„μΉ˜μΈ left와 right둜 mid 값을 μ •ν•΄μ€Œ(mid = (left + right) / 2)
  2. midκ°€ κ°€λ¦¬ν‚€λŠ” κ°’κ³Ό λͺ©ν‘œ κ°’(result)을 λΉ„κ΅ν•œλ‹€.

    1. mid > result, right = mid - 1
      midκ°€ κ°€λ¦¬ν‚€λŠ” 값보닀 λͺ©ν‘œ 값이 더 μž‘μ„ 경우, λͺ©ν‘œ 값이 절반 μ•„λž˜μͺ½μ— ν¬ν•¨λœ λ²”μœ„ μ•ˆμ— λ“€μ–΄μžˆκΈ° λ•Œλ¬Έμ— rightλ₯Ό mid - 1둜 μ„€μ •
    2. mid < result, left = mid + 1
      midκ°€ κ°€λ¦¬ν‚€λŠ” 값보닀 λͺ©ν‘œ 값이 더 클 경우, λͺ©ν‘œ 값이 절반 μœ„μͺ½ λ²”μœ„ μ•ˆμ— ν¬ν•¨λœ λ²”μœ„ μ•ˆμ— λ“€μ–΄μžˆκΈ° λ•Œλ¬Έμ— leftλ₯Ό mid + 1둜 μ„€μ •
  3. left > right κ°€ 될 λ•Œ κΉŒμ§€, ν˜Ήμ€ λͺ©ν‘œ 값을 찾을 λ•Œ κΉŒμ§€ 1~3 반볡

μ•žμ„œ μ„€λͺ…ν•œ 1κ³Ό 같이, νƒμƒ‰ν•˜λŠ” 배열은 λ°˜λ“œμ‹œ 미리 정렬이 λ˜μ–΄μžˆμ–΄μ•Ό ν•œλ‹€.

 

μ˜ˆμ‹œλ₯Ό 보면 이해가 쉽닀.

미리 μ •λ ¬λœ λ°°μ—΄ A = { 1, 2, 3, 4, 5, 6, 7, 8 } μ—μ„œ 찾고자 ν•˜λŠ” 값이 7μΌλ•Œ, 이뢄 탐색 과정은 λ‹€μŒκ³Ό κ°™λ‹€.

이 λ•Œ, 초기 left = 1, right = 8이닀.

1단계 : mid = (left + right) / 2 에 μ˜ν•΄ mid = 4κ°€ 되고, A[4]와 μ°ΎλŠ” λͺ©ν‘œ κ°’ 7을 λΉ„κ΅ν•˜μ˜€μ„ λ•Œ, A[4] < 7이기 λ•Œλ¬Έμ— leftλ₯Ό mid + 1인 5둜 μ„€μ •ν•œλ‹€.

2단계 : mid = (5 + 8) / 2 = 6이 되고, A[6]κ³Ό μ°ΎλŠ” λͺ©ν‘œ κ°’ 7을 λΉ„κ΅ν•˜μ˜€μ„ λ•Œ, A[6] < 7이기 λ•Œλ¬Έμ— leftλ₯Ό 7둜 μ„€μ •ν•œλ‹€.

3단계 : mid = (7 + 8) / 2 = 7이 되고, A[7]κ³Ό μ°ΎλŠ” λͺ©ν‘œ κ°’ 7을 λΉ„κ΅ν•˜μ˜€μ„ λ•Œ, A[7]κ³Ό 값이 μΌμΉ˜ν•˜κΈ° λ•Œλ¬Έμ— 이뢄 탐색을 μ’…λ£Œν•œλ‹€.

 


1.2 μ½”λ“œ

μ•Œκ³ λ¦¬μ¦˜μ˜ μ£Όμš” μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

int left = 0, right = N - 1;
int target, result;

while(left <= right) {
    int mid = (left + right) / 2;

    if(A[mid] == target) {
        result = A[mid];
        break;
    }
    else if(A[mid] < target) left = mid + 1;
    else right = mid - 1;
}

 

이λ₯Ό μ μš©ν•œ 전체 μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€. N개의 배열을 μž…λ ₯λ°›μ•„ μ •λ ¬ν•˜κ³ , νƒ€κ²Ÿμ„ μž…λ ₯받은 λ’€, νƒ€κ²Ÿμ„ 찾을 λ•Œ κΉŒμ§€ 이뢄 탐색을 μ‹€ν–‰ν•œλ‹€.

더보기
#include <vector>
#include <cstdio>
#include <algorithm>

using namespace std;

int main(void) {
    int N;
    scanf("%d", &N);
    vector<int> A;

    for(int i = 0; i < N; i++) {
        int temp;
        scanf("%d", &temp);
        A.push_back(temp);
    }

    sort(A.begin(), A.end()); // μ •λ ¬
    int left = 0, right = N - 1;
    int target, result;
    scanf("%d", &target);

    while(left <= right) {
        int mid = (left + right) / 2;

        if(A[mid] == target) {
            result = A[mid];
            break;
        }
        else if(A[mid] < target) left = mid + 1;
        else right = mid - 1;
    }

    printf("%d\n", result);
    return 0;
}
Comments