// education

02. 재귀(Recursion)와 분할 정복(Divide and Conquer) - 콜 스택, 팩토리얼 및 마스터 정리

자기 자신을 재귀적으로 호출하여 복잡한 문제를 단순한 하위 문제로 분해하는 **재귀(Recursion)**와 분할 정복(Divide and Conquer) 패러다임을 심도 있게 다룹니다.


1. 재귀 핵심 전문 용어 사전 (Glossary)


4. 실전 파이썬(Python 3) 알고리즘 구현 코드 및 라인별 주석 해설

본 레슨의 핵심 연산 매커니즘을 파이썬 3 환경에서 가장 효율적이고 직관적으로 구현한 실전 소스 코드입니다. 모든 주요 라인마다 상세한 한글 주석이 기재되어 있어 코드의 흐름을 쉽고 명확하게 이해할 수 있습니다.

import sys

# 파이썬 재귀 한계 설정 (기본 1,000회 제한을 100,000회로 확장하여 스택 오버플로우 방지)
sys.setrecursionlimit(10**5)

# 1. 재귀 팩토리얼 (Factorial)
def factorial(n: int) -> int:
    """N! 을 구하는 재귀 함수"""
    if n <= 1:  # [Base Case] n이 1 이하이면 즉시 1을 반환하며 재귀 탈출
        return 1
    # [Recursive Case] n * (n-1)! 형태로 문제를 더 작은 재귀로 분할
    return n * factorial(n - 1)

# 2. 하노이의 탑 (Hanoi Tower)
def hanoi(n: int, src: str, via: str, dst: str):
    """n개의 원판을 src에서 dst로 via를 거쳐 이동"""
    if n == 1:  # [Base Case] 원판이 1개일 때는 곧바로 dst로 이동
        print(f"원판 1 : {src} -> {dst}")
        return
    # 1단계: 상위 (n-1)개 원판을 경유지(via)로 이동
    hanoi(n - 1, src, dst, via)
    # 2단계: 가장 큰 n번째 원판을 목적지(dst)로 이동
    print(f"원판 {n} : {src} -> {dst}")
    # 3단계: 경유지(via)에 있던 (n-1)개 원판을 목적지(dst)로 이동
    hanoi(n - 1, via, src, dst)

# 3. 분할 정복 병합 정렬 (Merge Sort)
def merge_sort(arr: list) -> list:
    """분할 정복 기반 O(N log N) 병합 정렬"""
    if len(arr) <= 1:  # [Base Case] 원소가 1개 이하이면 이미 정렬된 상태
        return arr
    
    # 1. Divide (분할): 배열을 중앙 기준으로 두 조각으로 분할
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])   # 왼쪽 부분 배열 재귀 정렬
    right = merge_sort(arr[mid:])  # 오른쪽 부분 배열 재귀 정렬
    
    # 2. Combine (결합): 정렬된 두 부분 배열을 순서대로 병합
    merged = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            merged.append(left[i])
            i += 1
        else:
            merged.append(right[j])
            j += 1
    # 남은 원소들 일괄 추가
    merged.extend(left[i:])
    merged.extend(right[j:])
    return merged

if __name__ == "__main__":
    print("5! =", factorial(5))
    print("
[하노이의 탑 3개 원판 이동 경로]")
    hanoi(3, "A", "B", "C")
    print("
[병합 정렬 결과]:", merge_sort([38, 27, 43, 3, 9, 82, 10]))

파이썬 소스 코드 핵심 포인트 해설

  1. # [Base Case]: 재귀 호출을 멈추는 핵심 탈출 조건에 주석을 달아 무한 재귀를 막는 중요성을 강조했습니다.
  2. sys.setrecursionlimit(10**5): 파이썬 재귀 깊이 제한 오버플로우 예방 표준 구문입니다.
  3. merge_sort(): $O(N log N)$ 분할 정복 정렬로 리스트를 절반으로 쪼갠 후 재귀 결합하는 라인별 해설입니다.

5. 알고리즘 설계 및 최적화 실무 지침 (Best Practices & Complexity Audit)

02. 재귀(Recursion)와 분할 정복(Divide and Conquer) - 콜 스택, 팩토리얼 및 마스터 정리 레슨에서 익힌 핵심 알고리즘 메커니즘을 코딩 테스트 및 대규모 웹/서버 엔지니어링 환경에 도입할 때 반드시 체크해야 하는 튜닝 가이드입니다.

1) 공간/시간 복잡도 한계 및 메모리 사용 제어

2) 예외 케이스(Edge Cases) 및 코딩 테스트 체크리스트

  1. 입력 경계값 검증: $N=1$ 이거나 $N=0$ 인 극단적 최소 입력, 혹은 모든 요소의 값이 동일한 경우(Corner Case)에 대한 예외 처리를 누락하지 않습니다.
  2. 무한 루프 및 사이클 감지: 그래프/트리 탐색 시 방문 처리 배열(visited[])의 업데이트 위치를 정확히 지정하여 중복 큐 삽입으로 인한 메모리 초과를 예방합니다.

6. 핵심 요약 및 실무 FAQ (Summary & Q&A)

Q1. 파이썬 코드 주석에서 강조된 성능 핵심은 무엇인가요?

Q2. 실무 개발에서 본 파이썬 알고리즘 패턴은 어디에 활용되나요?

← 이전01. 알고리즘 성능 분석 기초 - 시간 복잡도, 공간 복잡도 및 Big-O 표기법 다음 →03. 정렬 알고리즘 1: 비교 정렬 - 버블 정렬(Bubble), 선택 정렬(Selection) 및 삽입 정렬(Insertion)