[필수 알고리즘] 이분 탐색(Binary Search) 이해

2023. 1. 25. 23:50·Back-End/알고리즘

이분/이진 탐색 Binary Search

정렬 등과 함께 가장 기초인 알고리즘으로 꼽히는 문제.

이진 탐색은 오름차순으로 정렬된 리스트에서 검색 범위를 줄여 나가면서 원하는 데이터를 검색하는 알고리즘이다.

 

이진 탐색은 정렬된 리스트에만 사용할 수 있다는 단점이 있지만,

검색이 반복될 때마다 검색 범위가 절반으로 줄기 때문에 속도가 빠르다는 장점이 있다.

 

이진 탐색 기법 활용

처음 중간의 값을 임의의 값으로 선택하여, 그 값과 찾고자 하는 값의 크고 작음을 비교하는 방식을 사용한다.

이때, 처음 선택한 중앙값이 만약 찾는 값보다 크면 그 값은 새로운 최댓값이 되며, 작으면 그 값은 새로운 최솟값이 된다.

  1. 배열의 중간 값을 가져온다.
  2. 중간 값과 검색 값을 비교한다.
    1. 중간 값이 검색 값과 같다면 종료한다. (mid = key)
    2. 중간 값보다 검색 값이 크다면 중간값 기준 배열의 오른쪽 구간을 대상으로 탐색한다. (mid < key)
    3. 중간 값보다 검색 값이 작다면 중간값 기준 배열의 왼쪽 구간을 대상으로 탐색한다. (mid > key)
  3. 값을 찾거나 간격이 비어있을 때까지 반복한다

 

활용 예시

key 값 39를 찾아보자.

1. 배열의 중간 값을 가져온다. (low = 0, high = 9, mid =4)

mid  = low + (high - low) / 2
          = 0 + (9-0)/2
          = 4

중앙값과 검색 값을 비교합니다.

A [4] (27) < key (39) 이므로 배열의 오른쪽 구간을 검색 범위로 정한다.

 

2. 배열의 중간 값을 가져온다. (low = 5, high = 9, mid = 7)

mid  = low + (high - low) / 2
          = 5 + (9-5)/2
          = 7

 중앙 값과 검색 값을 비교합니다.

A [7] (45) > key (39) 이므로 배열의 왼쪽 구간을 탐색 범위로 정한다.

 

3. 중앙 값을 결정  (low = 5, high = 6, mid = 5)

mid  = low + (high - low) / 2
        = 5 + (6-5)/2
        = 5

중앙값과 검색 값을 비교합니다.

A [5] (32) < key (39) 이므로 배열의 오른쪽 구간을 탐색 범위로 정한다.

그러고 나면 배열의 요소는 1개만 남았으므로 39가 되고 우리가 찾으려는 값과 일치하게 된다.

 

최악의 경우에는 배열의 사이즈가 1이 될 때까지 반으로 쪼개는 것이므로 (1 / 2) k * N = 1이고, 

양변에 로그를 취하여 정리하면, log2N이 되는 것을 알 수 있다.

따라서, 이진 탐색의 시간 복잡도는 O(logN) 이다.

 

종료조건

이진 탐색의 종료 조건은 두 가지가 있다.

다음 조건중 하나라도 성립하면 검색을 종료된다.

 

1. 검색을 성공할 경우

  • 리스트에서 검색할 값과 같은 요소를 발견한 경우
  • a [mid] == key

2. 검색을 실패한 경우

  • 더 이상 검색할 범위가 없을 경우
  • low > high

 

구현

반복문을 이용한 방법

public static int binarySearch(int arr[], int find) {
  int mid;
  int left = 0;
  int right = arr.length - 1;

  // 배열의 크기가 1이 될 때까지 반복.
  while (left <= right) {
    mid = (right + left) / 2;

    // 원하는 값을 찾았다면 그 위치를 반환.
    if (arr[mid] == find) {
      return mid;
    }

    if (find < arr[mid]) {
      right = mid - 1;
    } else {
      left = mid + 1;
    }
  }

  // 원하는 값을 찾지 못함.
  return -1;
}

 

재귀 함수를 이용한 방법

public static int binarySearch(int[] arr, int find, int left, int right) {
  // 원하는 값을 찾지 못함.
  if (left > right) {
    return -1;
  }

  int mid = (left + right) / 2;
  
  // 원하는 값을 찾았다면 그 위치를 반환.
  if (find == arr[mid]) {
    return mid;
  }

  if (find > arr[mid]) {
    return binarySearch(arr, find, mid + 1, right);
  }
  return binarySearch(arr, find, left, mid - 1);
}

 

'Back-End > 알고리즘' 카테고리의 다른 글

[필수 알고리즘] 다익스트라 알고리즘(Dijkstra Algorithm) 이해  (0) 2023.02.18
[필수 알고리즘] 그리디 알고리즘(Greedy Algorithm) 이해  (0) 2023.02.03
[필수 알고리즘] 동적계획법 DP (Dynamic Programming) 이해  (0) 2023.01.25
[필수 알고리즘] BFS 너비 우선 탐색 (Queue 구조) 이해  (2) 2023.01.16
[필수 알고리즘] DFS 깊이 우선 탐색 (Stack 구조) 이해  (1) 2023.01.12
'Back-End/알고리즘' 카테고리의 다른 글
  • [필수 알고리즘] 다익스트라 알고리즘(Dijkstra Algorithm) 이해
  • [필수 알고리즘] 그리디 알고리즘(Greedy Algorithm) 이해
  • [필수 알고리즘] 동적계획법 DP (Dynamic Programming) 이해
  • [필수 알고리즘] BFS 너비 우선 탐색 (Queue 구조) 이해
COBI-98
COBI-98
배운 것을 응용하기 위해 기록하는 것을 선호하며 백엔드를 공부하고 있습니다.
  • COBI-98
    은로그
    COBI-98
  • 전체
    오늘
    어제
    • 은로그 (79)
      • Back-End (32)
        • Java (5)
        • Spring (16)
        • DB (1)
        • 알고리즘 (7)
        • ETC (2)
      • 개발 일기 (0)
      • 회고 (4)
      • Project (10)
        • 협업프로젝트 (7)
        • 국비프로젝트 (2)
      • Web (2)
        • Server (2)
      • Git (2)
      • CS (0)
      • 코딩테스트 (24)
        • 백준 (17)
        • 프로그래머스 (7)
      • 우아한 테크코스 (5)
  • 블로그 메뉴

    • ✨깃허브
    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    배민
    배달의민족
    재귀
    elk
    프로그래머스
    BFS
    Spring
    Java
    레벨2
    김영한님
    큐
    N과 M
    재귀알고리즘
    코딩테스트
    깊이 우선 탐색
    2단계
    백준Java
    김영한강의
    DFS
    백준
    백엔드
    재귀함수
    inflean
    우아한테크코스
    우테코
    우아한형제들
    코테
    인프런
    백트래킹
    그리디 알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
COBI-98
[필수 알고리즘] 이분 탐색(Binary Search) 이해
상단으로

티스토리툴바