새소식

반응형
컴퓨터공학 (Computer Science)/┣ 탐색 | Search

이진탐색 ( 이분탐색, Binary Search)의 모든 것

  • -
반응형

이진탐색은 정렬된 리스트에 적용할 수 있는 간단한 고속 탐색 기법이다.

해시 같은 매핑 기반의 기법을 제외한다면 가장 빠른 탐색 속도를 보장한다.


이진탐색의 핵심은 전체 탐색범위를 반으로 나눠서 찾고자 하는 원소 (이하 target, T)가 없을 것으로 기대되는 쪽을 버리는 것이다. 이를 통해 탐색범위는 기존의 탐색범위의 12이 되고, 이 새로운 탐색 범위에 반을 버려가는 과정을 반복하여 결과적으로 target을 찾아내는 방법이다.

과정을 자세하게 알아보자.

  1. 탐색을 원하는 구간 [a, b]에 대해 a를 low, b를 high라고 하자. (당연히 low, high는 index이다)
  2. low와 high의 중간 값을 mid라고 하자.
  3. 탐색할 리스트를 temp라고 하면 temp[mid]와 target의 값을 비교한다. (즉, value끼리 비교한다)
  4. target이 크다면 mid가 새로운 low가 된다 (즉, 왼쪽반을 버림). target이 작다면 반대로. 
  5. 1~4를 반복
  6. 만약 temp[mid]와 target이 같다면 mid를 return.
  7. low와 high가 같을 때까지 못 찾았다면 error (false, -1등 다양함)를 return.

이 과정을 이미지를 통해 시각적으로 이해해보자.

Average-case of Binary Search

 

Worst-case of Binary Search

 

Best-case of Binary Search

 

다음은 recursive한 이진 탐색의 pseudo-code이다.

BinarySearch(A[0..N-1], target, low, high) { if (high <= low) return -1 // not found mid = (low + high) / 2 if (A[mid] > target) return BinarySearch(A, target, low, mid-1) else if (A[mid] < value) return BinarySearch(A, target, mid+1, high) else return mid // found }

 

다음은 non-recursive한 이진 탐색의 pseudo-code이다.

BinarySearch(A[0..N-1], target, low, high) { for (low <= high) mid = (low + high) / 2 if (A[mid] < target) low = mid + 1 else if (A[mid] > target) high = mid - 1 else return mid // found return -1 // not found }

  • Best-case Performance   : O(1)
  • Worst-case Performance : O(logn)
  • Average Performance      : O(logn)
  • Space Complexity            : O(1) (non-recursive),  O(logn) (recursive)

가끔 보다보면 mid 값을 설정할 때, 단순히 mid=(low+high)2가 아니라 low+(highlow)2를 주는 경우를 볼 수 있다.

이것은 약간의 산술 연산을 더해서 low + high가 overflow 나는 경우에도 코드가 동작할 수 있도록 짠 것이다.

또 매 iteration마다 a[mid]가 target과 같은지 확인하고 있는데 이 부분을 빼고 항상 low가 high와 같아질 때까지 돌리고 마지막에 한번만 a[mid]가 target과 같은지 확인해도 된다. 이 방법은 기존 코드의 alternative한 방법으로 뒤에서 더 자세하게 다룬다.

a 배열이 만약 중복이 허용된 배열이라면, 이진 검색으로 Target을 찾는데에 오류는 없지만 그 결과가 항상 중복 원소의 첫번째 위치를 보장해주지는 않는다. 첫번째 위치를 찾는 일은 종종 쓸모가 있는데 (e.g. Rank), 이 경우 가장 중복 원소의 가장 왼쪽 자리 (leftmost element)를 찾아야 한다. 이 때, 위의 alternative한 방법을 쓴다 (가장 오른쪽 자리도 마찬가지). 

이진검색은 정렬된 배열에서 원하는 원소를 탐색하는 기법이므로 Approximate match가 가능하다.

  • Predecessor (전위자)는 leftmost element의 결과값 r에대해, r-1과 같다.
  • Successor (후위자)는 rightmost element의 결과값 r에 대해, r+1과 같다.
  • Rank는 leftmost element의 결과와 같다.
  • Nearest element는 Predecessor과 Successor중에 더 가까운 값과 같다.
  • Range query (범위 안에 해당하는 값들에 대한 인덱스)는 범위 (a, b)에 대해 a의 Successor부터 b의 Predecessor까지의 인덱스와 같다.

 

반응형

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.