보간 탐색(Interpolation Search)

코딩하는코린이·2023년 8월 3일

보간 탐색이란

보간 탐색(Interpolation Search)은 정렬된 배열에서 원하는 값을 탐색하는 알고리즘 중 하나입니다. 이 알고리즘은 이진 탐색(Binary Search)과 유사하며, 이진 탐색보다 더 빠른 검색 속도를 제공할 수 있습니다.

이진 탐색은 배열의 중간 요소를 기준으로 원하는 값을 찾아가는 반면, 보간 탐색은 배열 내의 값들이 균등하게 분포되어 있다고 가정하고, 타겟 값이 있을 법한 위치를 보다 빠르게 찾기 위해 사용됩니다.

보간 탐색의 시간 복잡도는 보통 O(log(log n)) 수준으로 추정됩니다. 하지만 배열의 분포가 균등하지 않거나 값들이 많이 겹치는 경우에는 성능이 떨어질 수 있습니다.

보간 탐색 동작 방식

  1. 배열이 정렬되어 있어야 합니다.
  2. 타겟 값을 찾을 범위를 결정하기 위해 배열의 최솟값과 최댓값을 이용합니다.
  3. 타겟 값의 예상 위치를 계산하기 위해 선형 보간 interpolation)을 사용합니다.
  • 예상 위치 = 최솟값 + (타겟 값 - 배열[최솟값]) * (최댓값 - 최솟값) / (배열[최댓값] - 배열[최솟값])
  1. 예상 위치와 타겟 값을 비교합니다.
  • 만약 예상 위치의 값이 타겟 값보다 크다면, 최댓값을 예상 위치 바로 이전 인덱스로 변경하여 범위를 좁힙니다.
  • 만약 예상 위치의 값이 타겟 값보다 작다면, 최솟값을 예상 위치 바로 다음 인덱스로 변경하여 범위를 좁힙니다.
  • 찾은 값과 타겟 값이 일치하면 탐색을 종료합니다.
  1. 찾을 때까지 위의 단계를 반복합니다.

보간 탐색의 장단점

장점:

  1. 빠른 탐색 속도: 보간 탐색은 이진 탐색보다 평균적으로 더 빠른 탐색 속도를 제공합니다. 배열 내 값들의 분포가 균등하고 빠르게 수렴하는 경우에 특히 효과적입니다.

  2. 이진 탐색보다 더 가까운 값 탐색 가능: 보간 탐색은 배열 내 값들의 분포를 고려하여 예상 위치를 계산하므로, 이진 탐색보다 찾으려는 값과 더 가까운 위치에서 탐색을 시작할 수 있습니다.

  3. 적은 비교 횟수: 이진 탐색은 항상 배열의 중간 값을 비교해야 하지만, 보간 탐색은 예상 위치를 기반으로 탐색 범위를 좁혀나가기 때문에 비교 횟수가 줄어들 수 있습니다.

단점:

  1. 배열 분포에 민감: 배열 내 값들의 분포가 불균형하거나 값들이 많이 겹치는 경우 성능이 저하될 수 있습니다. 이런 경우에는 이진 탐색이 더 좋은 선택일 수 있습니다.

  2. 무작위 접근 비효율성: 보간 탐색은 일정한 규칙에 따라 탐색 범위를 축소하므로 배열의 무작위 접근에는 부적합합니다. 이러한 상황에서는 해시 테이블 등 다른 자료 구조를 고려하는 것이 좋습니다.

  3. 추가 연산 비용: 보간 탐색은 예상 위치를 계산하는 추가 연산이 필요합니다. 이진 탐색보다 더 많은 계산이 필요하며, 이로 인해 일부 상황에서는 이진 탐색보다 느릴 수 있습니다.

요약하면, 보간 탐색은 평균적으로 이진 탐색보다 빠르고 더 가까운 값을 탐색할 수 있으며, 적은 비교 횟수를 필요로 합니다. 하지만 배열 내 값들의 분포에 민감하고, 무작위 접근에 비효율적이며, 추가적인 연산 비용이 발생할 수 있습니다. 따라서 문제의 특성과 데이터의 분포를 고려하여 적절한 탐색 알고리즘을 선택해야 합니다.

구현

def interpolation_search(arr, target):
    left = 0
    right = len(arr) - 1
    
    while left <= right and arr[left] <= target <= arr[right]:
        # 예상 위치를 계산
        pos = left + ((target - arr[left]) * (right - left)) // (arr[right] - arr[left])
        
        if arr[pos] == target:
            return pos
        elif arr[pos] < target:
            left = pos + 1
        else:
            right = pos - 1
    
    return -1

arr = [2, 5, 8, 12, 16, 23, 38, 45, 56, 72, 91]
target = 23
result = interpolation_search(arr, target)

if result != -1:
    print(f"찾고자 하는 값 {target}은 인덱스 {result}에 있습니다.")
else:
    print(f"찾고자 하는 값 {target}은 배열에 존재하지 않습니다.")
profile
$ 1M이 목표인 20대 개발자

0개의 댓글