Go에서 재귀 함수로 이진 탐색(Binary Search) 구현하기

Golang

이진 탐색(Binary Search)은 정렬된 배열에서 원하는 값을 빠르게 찾는 알고리즘입니다. 검색 범위를 절반씩 줄이기 때문에 시간 복잡도는 O(log n)으로 매우 효율적입니다.

보통 이진 탐색은 반복문(loop)으로 구현하지만, Go에서는 재귀 함수(Recursive Function)를 통해 더 깔끔하고 직관적인 방식으로 구현할 수도 있습니다.

이번 글에서는 Go 언어를 사용해 재귀 방식으로 Binary Search를 구현하는 방법을 자세히 살펴보겠습니다.


이진 탐색이란?

이진 탐색은 다음 조건에서 사용됩니다:

  • 배열이 오름차순(또는 내림차순)으로 정렬되어 있을 것
  • 인덱스를 기준으로 중간 값을 선택하고, 찾고자 하는 값과 비교
  • 크기를 기준으로 왼쪽 절반 또는 오른쪽 절반만 계속 탐색

예를 들어, [1, 3, 5, 7, 9, 11] 에서 7을 찾는다면:

  • 중간값 5 < 7 → 오른쪽으로 이동
  • 다음 중간값 9 > 7 → 왼쪽으로 이동
  • 다음 중간값 7 → 찾음!

Go로 구현한 재귀 이진 탐색 함수

package main

import (
    "fmt"
)

// 재귀 이진 탐색 함수
func binarySearch(arr []int, target int, low int, high int) int {
    if low > high {
        return -1 // 못 찾은 경우
    }

    mid := (low + high) / 2

    if arr[mid] == target {
        return mid
    } else if arr[mid] > target {
        return binarySearch(arr, target, low, mid-1)
    } else {
        return binarySearch(arr, target, mid+1, high)
    }
}

사용 예시

func main() {
    sortedArr := []int{1, 3, 5, 7, 9, 11, 13}
    target := 7

    result := binarySearch(sortedArr, target, 0, len(sortedArr)-1)

    if result != -1 {
        fmt.Printf("값 %d는 인덱스 %d에 있습니다.\n", target, result)
    } else {
        fmt.Printf("값 %d를 배열에서 찾을 수 없습니다.\n", target)
    }
}

출력 결과

값 7는 인덱스 3에 있습니다.

시간 복잡도

  • 최악의 경우 (O(log n)): 배열의 크기를 절반씩 줄이기 때문에, log₂(n) 만큼만 비교하면 됨
  • 공간 복잡도 (재귀 호출): O(log n)만큼 스택이 사용됨 (반복문은 O(1) 공간 사용)

Go다운 방식으로 구현 팁

Go에서는 불필요한 전역 변수를 피하고함수를 명확하게 분리하는 것이 좋습니다. 그래서 다음처럼 wrapper 함수를 만들어 더 깔끔하게 사용할 수 있습니다:

func BinarySearch(arr []int, target int) int {
    return binarySearch(arr, target, 0, len(arr)-1)
}

사용자는 내부 인덱스를 몰라도 간단하게 사용할 수 있습니다:

result := BinarySearch([]int{1, 3, 5, 7, 9}, 5)

반복문 vs 재귀문: 어느 쪽이 좋을까?

방식장점단점
반복문공간 효율성 (O(1)), 빠름코드가 다소 장황할 수 있음
재귀 함수코드 간결성, 직관적인 구조큰 배열에서는 스택 오버플로우 위험

실무에서는 반복문이 더 자주 사용되지만, 알고리즘 공부나 간결한 코드 구현에는 재귀도 훌륭한 선택입니다.


마무리

이진 탐색은 알고리즘 학습자라면 반드시 익혀야 할 기초 중의 기초입니다. Go 언어의 재귀 함수를 활용하면, 이진 탐색 로직을 더 직관적이고 명확하게 표현할 수 있습니다.

처음엔 간단한 배열부터 시작해서, 점차 구조체 정렬이나 사용자 정의 타입으로 확장해보세요. 그렇게 한 발씩 나아가는 것이 Go 언어 실력을 쌓는 가장 좋은 방법입니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤