πŸ“š Binary search

πŸ“š 이진 탐색(Binary search)


🎯 이진 νƒμƒ‰μ΄λž€?

  • μ •λ ¬λœ λ°°μ—΄μ΄λ‚˜ λ¦¬μŠ€νŠΈμ—μ„œ νŠΉμ • 값을 효율적으둜 μ°ΎλŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.
  • 이진 탐색은 반으둜 λ‚˜λˆ„μ–΄κ°€λ©° 검색을 μ§„ν–‰ν•˜κΈ° λ•Œλ¬Έμ— μ‹œκ°„ λ³΅μž‘λ„κ°€ 맀우 λΉ λ₯΄λ‹€(O(logn))의 μ‹œκ°„ λ³΅μž‘λ„, 즉 λ°°μ—΄μ˜ 크기가 컀져도 탐색 νšŸμˆ˜κ°€ κΈ‰κ²©νžˆ μ¦κ°€ν•˜μ§€ μ•ŠμŒ 을 μ˜λ―Έν•œλ‹€.

πŸ’‘ 이진 νƒμƒ‰μ˜ μž‘λ™ 원리

  1. λ°°μ—΄ μ •λ ¬
    • 이진 탐색은 **λ°˜λ“œμ‹œ μ •λ ¬λœ λ°°μ—΄** μ—μ„œλ§Œ μž‘λ™ν•œλ‹€
  2. 쀑앙값 계산
    • λ°°μ—΄μ˜ 쀑앙에 μžˆλŠ” 값을 ν™•μΈν•œλ‹€. κ·Έ 값이 찾고자 ν•˜λŠ” 값이라면 탐색 μ’…λ£Œ
  3. κ°’ 비ꡐ
    • μ°Ύκ³ μžν•˜λŠ” 값이 쀑앙값보닀 크면, 탐색 λ²”μœ„λ₯Ό μ€‘μ•™κ°’μ˜ 였λ₯Έμͺ½ 절반으둜 μ€„μž„
    • μ°Ύκ³ μžν•˜λŠ” 값이 쀑앙값보닀 μž‘μœΌλ©΄, 탐색 λ²”μœ„λ₯Ό μ€‘μ•™κ°’μ˜ μ™Όμͺ½ 절반으둜 μ€„μž„
  4. μž¬κ·€μ  ν˜Ήμ€ 반볡적 탐색
    • λ°°μ—΄μ˜ λ²”μœ„κ°€ μ’μ•„μ§ˆ λ•ŒκΉŒμ§€ 이 과정을 반볡, 더 이상 찾을 값이 μ—†μœΌλ©΄, μ°Ύμ§€ λͺ»ν–ˆλ‹€λŠ” κ²°κ³Όλ₯Ό λ°˜ν™˜(보톡 -1)

πŸ’» 이진 탐색 μ˜ˆμ‹œ

#include <iostream>

using namespace std;


int binary_search(const vector<int>& arr, int target) {
    int low = 0;
    int high = arr.size() - 1; // index의 크기

    while(low<=high)
    {
        int mid = low + (high - low) / 2 //쀑간값 계산(μ˜€λ²„ν”Œλ‘œμš° λ°©μ§€)

        if(arr[mid] == target)
        {
            return mid; // 쀑앙값과 찾고자 ν•˜λŠ” 값이 κ°™μœΌλ©΄ midλ₯Ό 리턴
        }
        else if(arr[mid] <  target)
        {
            low = mid + 1; // λ°°μ—΄μ˜ 쀑앙값이 찾고자 ν•˜λŠ” 값보닀 μž‘μœΌλ©΄ 더 였λ₯Έμͺ½μ— μžˆλ‹€λŠ” λœ»μ΄λ‹ˆκΉ 탐색 λ²”μœ„λ₯Ό 였λ₯Έμͺ½μœΌλ‘œ μ’νžŒλ‹€.
        }
        else
        {
            high = mid - 1; // λ°°μ—΄μ˜ 쀑앙값이 찾고자 ν•˜λŠ” 값보닀 크면 μ™Όμͺ½μ— μžˆλ‹€λŠ” λœ»μ΄λ‹ˆκΉ 탐색 λ²”μœ„λ₯Ό μ™Όμͺ½μœΌλ‘œ μ’νžŒλ‹€.
        }
    }

    return -1; //μ°Ύμ§€ λͺ»ν•œλ‹€λ©΄ -1 리턴

}

int main()
{

    vector<int> arr = {1, 3, 5, 7, 9, 10};

    int target = 7;
    int result = binary_search(arr, target);

    if(result == -1)
    {
        cout << "μ°Ύμ§€ λͺ»ν•¨!" << endl;
    }
    else
    {
        cout << "찾음!" << result << endl;
    }

    return 0;
}


πŸ’» 이진 νƒμƒ‰μ˜ μž¬κ·€μ  κ΅¬ν˜„

#include <iostream>
#include <vector>

int binarySearchRecursive(const std::vector<int>& arr, int target, int low, int high) {
    if (low > high) return -1;  // 값을 μ°Ύμ§€ λͺ»ν–ˆμ„ 경우

    int mid = low + (high - low) / 2;

    if (arr[mid] == target) {
        return mid;  // 값이 쀑간값과 μΌμΉ˜ν•˜λ©΄ κ·Έ 인덱슀λ₯Ό λ°˜ν™˜
    } else if (arr[mid] < target) {
        return binarySearchRecursive(arr, target, mid + 1, high);  // 였λ₯Έμͺ½ 절반으둜
    } else {
        return binarySearchRecursive(arr, target, low, mid - 1);  // μ™Όμͺ½ 절반으둜
    }
}

int main() {
    std::vector<int> arr = {1, 3, 5, 7, 9, 11, 13, 15};

    int target = 7;
    int result = binarySearchRecursive(arr, target, 0, arr.size() - 1);

    if (result != -1) {
        std::cout << "Element found at index: " << result << std::endl;
    } else {
        std::cout << "Element not found" << std::endl;
    }

    return 0;
}

πŸ“Œ 이진 νƒμƒ‰μ˜ μ£Όμš”νŠΉμ§•

  1. μ‹œκ°„ λ³΅μž‘λ„
    • (O(logn)) 둜, 탐색 λ²”μœ„κ°€ μ ˆλ°˜μ”© 쀄어듀기 λ•Œλ¬Έμ— 맀우 λΉ λ₯΄λ‹€.
  2. 곡간 λ³΅μž‘λ„
    • (O(1)) (반볡문 μ‚¬μš©μ‹œ), μž¬κ·€ ν˜ΈμΆœμ„ μ‚¬μš©ν•˜λ©΄ 호좜 μŠ€νƒμ΄ ν•„μš”ν•˜λ―€λ‘œ (O(logn)) 이 될 μˆ˜λ„ μžˆλ‹€.
  3. μ •λ ¬λœ λ°°μ—΄μ—μ„œλ§Œ λ™μž‘
    • binary search μ—μ„œ κ°€μž₯ μ€‘μš”ν•œ 이둠
    • 이진 탐색을 μ‚¬μš©ν•˜λ €λ©΄ λ°°μ—΄μ΄λ‚˜ λ¦¬μŠ€νŠΈκ°€ λ°˜λ“œμ‹œ μ •λ ¬λ˜μ–΄ μžˆμ–΄μ•Όν•œλ‹€.
    • λ§Œμ•½ μ •λ ¬λ˜μ–΄ μžˆμ§€ μ•Šλ‹€λ©΄, λ¨Όμ € 정렬을 ν•΄μ•Όν•œλ‹€.
  4. μ •ν™•ν•œ 값을 μ°Ύμ§€ λͺ»ν–‡μ„ 경우
    • 값을 μ°Ύμ§€ λͺ»ν–ˆμ„ 경우 일반적으둜 β€˜-1’ 을 λ°˜ν™˜ν•œλ‹€. λ˜λŠ” nullptr(포인터일 경우)λ₯Ό λ°˜ν™˜ν•œλ‹€.

πŸ”Ž 정리

이진 탐색은 μ½”λ”© ν…ŒμŠ€νŠΈμ— κΌ­ ν•„μš”ν•œ κ°œλ…μ΄λ‹€. 탐색 속도가 λΉ λ₯Έλ§ŒνΌ 무쑰건 μ •λ ¬λœ 데이터 μ—μ„œλ§Œ μ‚¬μš© κ°€λŠ₯μ΄λΌλŠ” 쑰건이 λΆ™μ–΄μžˆλ‹€.