본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 재귀 함수(Recursive Function)의 마법 : 원리와 실전 설계 전략

by Papa Martino V 2026. 2. 13.
728x90

재귀 함수(Recursive Function)
재귀 함수(Recursive Function)

단순 반복문을 넘어 논리적 우아함을 구현하는 재귀적 사고방식(Recursive Thinking)의 모든 것


1. 재귀 함수란 무엇인가? (The Essence of Recursion)

프로그래밍의 세계에서 재귀(Recursion)는 함수가 자기 자신을 다시 호출하여 문제를 해결하는 기법을 말합니다. 이는 마치 거울 두 개를 마주 보게 놓았을 때 끝없이 펼쳐지는 이미지나, 러시아의 인형 '마트료시카'와 같습니다. 커다란 인형을 열면 똑같이 생긴 조금 더 작은 인형이 나오고, 그 안에 또 작은 인형이 들어있는 구조와 매우 흡사합니다. 재귀는 복잡한 문제를 동일한 형태의 더 작은 하위 문제(Sub-problems)로 쪼개어 해결할 때 매우 강력한 위력을 발휘합니다. 특히 자료구조의 트리(Tree)나 그래프(Graph) 탐색, 정렬 알고리즘 등에서 코드를 극적으로 간결하게 만들어주는 핵심 도구입니다.

2. 재귀 함수의 두 가지 필수 구성 요소

재귀 함수를 설계할 때 가장 중요한 것은 '무한 루프'에 빠지지 않는 것입니다. 이를 위해 모든 재귀 함수는 반드시 다음 두 가지 요소를 갖춰야 합니다.

  • 기저 조건 (Base Case): 재귀 호출을 멈추고 값을 반환하는 지점입니다. 이 조건이 없으면 함수는 메모리가 가득 찰 때까지(Stack Overflow) 자기 자신을 호출합니다.
  • 재귀 단계 (Recursive Step): 문제를 더 작은 단위로 쪼개어 자기 자신을 다시 호출하는 부분입니다. 이때 인자값은 반드시 기저 조건에 가까워지는 방향으로 변화해야 합니다.

3. 심층 비교: 재귀(Recursion) vs 반복문(Iteration)

모든 재귀 함수는 이론적으로 반복문으로 변환이 가능합니다. 하지만 상황에 따라 선택해야 할 기준이 다릅니다.

항목 재귀 함수 (Recursion) 반복문 (Iteration)
코드 가독성 수학적 정의에 가까워 매우 직관적임 로직이 복잡해질수록 가독성이 떨어질 수 있음
메모리 사용 스택(Stack) 메모리를 지속적으로 소모 상대적으로 적은 메모리 소모
실행 속도 함수 호출 오버헤드로 인해 약간 느릴 수 있음 직접적인 값의 변경으로 속도가 빠름
적합한 분야 분할 정복, 트리 탐색, 하노이의 탑 순차 데이터 처리, 단순 합계 계산 등
위험 요소 Stack Overflow 발생 가능성 무한 루프(Infinite Loop) 발생 가능성

4. 실전 예제: 팩토리얼(Factorial)과 피보나치(Fibonacci)

재귀 함수의 가장 고전적이고 명확한 예시인 팩토리얼 계산을 통해 파이썬 코드를 살펴보겠습니다.

[Sample Example 1] 팩토리얼 계산

def factorial(n):
    # 1. 기저 조건
    if n <= 1:
        return 1
    # 2. 재귀 단계
    return n * factorial(n - 1)

print(factorial(5))  # 결과: 120 (5 * 4 * 3 * 2 * 1)

[Sample Example 2] 피보나치 수열 (효율적 개선 포함)

단순 재귀로 피보나치를 구현하면 중복 계산이 많아집니다. 이를 해결하기 위해 메모이제이션(Memoization) 기법을 결합하는 것이 실무적인 정석입니다.

def fibonacci(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 2:
        return 1
    
    memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo)
    return memo[n]

print(fibonacci(50))  # 결과: 12586269025 (순수 재귀보다 압도적으로 빠름)

5. 파이썬 재귀의 한계와 주의사항

파이썬은 시스템 보호를 위해 재귀 깊이 제한(Recursion Limit)을 두고 있습니다. 기본값은 보통 1,000회입니다. 이를 초과하면 RecursionError가 발생합니다.

전문가 팁: 대규모 데이터를 처리해야 한다면 sys.setrecursionlimit()을 통해 제한을 늘리거나, 꼬리 재귀 최적화(Tail Call Optimization)가 지원되지 않는 파이썬 특성상 반복문으로 설계하는 것이 안전합니다.

6. 결론: 언제 재귀를 써야 하는가?

재귀 함수는 문제를 바라보는 관점을 바꾸어줍니다. "어떻게(How) 계산할까"보다 "무엇이(What) 문제의 본질인가"에 집중하게 합니다. 트리 구조의 폴더를 탐색하거나, JSON 데이터를 파싱하는 등 계층적 구조를 다룰 때 재귀는 그 어떤 반복문보다 강력하고 아름다운 코드를 선사합니다.

7. 내용 출처

  • Python Software Foundation - "Official Documentation: Recursion"
  • Introduction to Algorithms (CLRS) - MIT Press
  • GeeksforGeeks - "Recursion in Python"
728x90