
재귀는 함수가 자기 자신을 호출하는 기법
하지만 이 한 줄로는 이해가 어려움!
중요한 건 재귀 호출이 “트리”처럼 확장되며 진행
따라서 재귀는 “Level이 깊어지면서 Branch가 나뉘고, 다시 Base Case에서 위로 합쳐지며 값이 반환되는 과정”
function recursive(parameter):
if (종료 조건): // Base Case
return 결과
else: // Recursive Case
recursive(더 작은 문제)
return 결과
Base Case: 더 이상 호출하지 않고 종료하는 조건. 없으면 무한루프 발생
Recursive Case: 문제를 더 작은 단위로 쪼개어 자기 자신을 호출
수학적 정의
n! = n × (n-1)!
0! = 1
파이썬 코드 (주석 포함)
def factorial(n, level=0):
# level은 현재 함수 호출 깊이를 나타냄
indent = " " * level
print(f"{indent}▶ factorial({n}) 호출 (level={level})")
if n == 0: # Base Case
print(f"{indent}◀ Base Case 도달: factorial(0)=1 반환")
return 1
# Recursive Case
# 현재 n을 다음 호출(factorial(n-1)) 결과와 곱함
result = n * factorial(n-1, level+1)
print(f"{indent}◀ factorial({n}) = {n} * factorial({n-1}) = {result} (level={level})")
return result
print("최종 결과:", factorial(3))
실행 흐름
▶ factorial(3) 호출 (level=0)
▶ factorial(2) 호출 (level=1)
▶ factorial(1) 호출 (level=2)
▶ factorial(0) 호출 (level=3)
◀ Base Case 도달: factorial(0)=1 반환
◀ factorial(1) = 1 * factorial(0) = 1 (level=2)
◀ factorial(2) = 2 * factorial(1) = 2 (level=1)
◀ factorial(3) = 3 * factorial(2) = 6 (level=0)
최종 결과: 6
여기서 인자 변화를 보면:
n=3n=2n=1n=0 (Base Case)이전 호출의 인자(
n)가 한 단계 줄어든 값으로 다음 호출에 전달되고,
반환값이 거꾸로 올라오면서 곱해짐
정의
F(0)=0, F(1)=1
F(n)=F(n-1)+F(n-2)
코드
def fib(n, level=0):
indent = " " * level
print(f"{indent}▶ fib({n}) 호출 (level={level})")
if n == 0:
print(f"{indent}◀ Base Case: fib(0)=0 반환")
return 0
if n == 1:
print(f"{indent}◀ Base Case: fib(1)=1 반환")
return 1
# Branch: 두 방향으로 갈라짐
left = fib(n-1, level+1) # fib(n-1)
right = fib(n-2, level+1) # fib(n-2)
result = left + right
print(f"{indent}◀ fib({n}) = {left}+{right}={result} (level={level})")
return result
print("최종 결과:", fib(4))
실행 흐름 (fib(4))
▶ fib(4) 호출 (level=0)
▶ fib(3) 호출 (level=1)
▶ fib(2) 호출 (level=2)
▶ fib(1) 호출 (level=3)
◀ Base Case: fib(1)=1 반환
▶ fib(0) 호출 (level=3)
◀ Base Case: fib(0)=0 반환
◀ fib(2) = 1+0=1 (level=2)
▶ fib(1) 호출 (level=2)
◀ Base Case: fib(1)=1 반환
◀ fib(3) = 1+1=2 (level=1)
▶ fib(2) 호출 (level=1)
...
◀ fib(4) = 2+1=3 (level=0)
Branch 강조:
fib(n)은 항상fib(n-1)과fib(n-2)두 갈래(branch)로 분기
인자 연관성: 현재n값에서 두 개의 작은 문제(n-1,n-2)로 쪼깸
규칙
코드
def hanoi(n, start, target, auxiliary, level=0):
indent = " " * level
if n == 1:
print(f"{indent}Move disk 1 from {start} → {target}")
return
# Branch 1: N-1개를 start→auxiliary
hanoi(n-1, start, auxiliary, target, level+1)
print(f"{indent}Move disk {n} from {start} → {target}")
# Branch 2: N-1개를 auxiliary→target
hanoi(n-1, auxiliary, target, start, level+1)
hanoi(3, 'A', 'C', 'B')
실행 결과
Move disk 1 from A → C
Move disk 2 from A → B
Move disk 1 from C → B
Move disk 3 from A → C
Move disk 1 from B → A
Move disk 2 from B → C
Move disk 1 from A → C
Level: 원판 개수(n)가 줄어들며 재귀 깊이가 깊어짐
Branch: "왼쪽 branch → 중앙 작업 → 오른쪽 branch"
❌ 오개념 1: “재귀가 무한히 돌 것 같다”
RecursionError 발생❌ 오개념 2: “return 값이 어디로 가는지 모르겠다”
factorial(0)이 1을 반환하면 → factorial(1)에서 1*1=1 계산 → 다시 반환 → factorial(2)로 전달 → 이런 식으로 거슬러 올라감❌ 오개념 3: “모든 호출이 동시에 실행된다”
즉, 재귀의 핵심은 “함수 호출 스택이 트리처럼 확장되며, 인자(parameter)가 작아지거나 바뀌면서 Base Case까지 진행한 후 다시 위로 합쳐지는 과정”을 이해하는 것
백준 10870번 피보나치 수 5
→ 기본 재귀 호출과 Base Case/Recursive Case 감 잡기
백준 17478번 재귀함수가 뭔가요?
→ level(깊이)에 따라 다른 출력이 필요한 문제. 재귀 구조 이해하기에 최적
백준 11729번 하노이 탑 이동 순서
→ 재귀적 사고를 트리 구조로 확장해보는 문제