문제 : 여러 겹으로 포장된 상자들이 있고, 그 상자가 또 다른 상자들 속에 들어 있다. 몇 개일지 모르는 상자들 중 열쇠가 들어있는 상자를 찾아야 한다.
아래는 위 과정에 대한 슈도코드.
def look_for_key(main_box):
pile = main_box.make_a_pile_to_look_through()
while pile is not empty:
box = pile.grab_a_box()
for item in box:
if item.is_a_box():
pile.append(item)
elif item.is_a_key():
print "열쇠를 찾았어요!"
아래는 위 과정에 대한 슈도코드.
def look_for_key(box):
for item in box:
if item.is_a_box():
look_for_key(item)
elif item.is_a_key():
print "열쇠를 찾았어요!"
재귀함수는 자기 자신을 호출하기 때문에 무한루프에 빠지기 쉽다.
재귀함수를 만들 때에는 언제 재귀를 멈출지 반드시 알려 주어야 한다.
그래서 모든 재귀함수는 기본 단계와 재귀 단계로 나누어져 있다.
아래는 카운트다운을 하는 코드. (무한루프)
def countdown(i):
print i
countdown(i-1)
무한루프 코드에 기본 단계를 추가하면 정상 동작하는 재귀함수를 만들 수 있다.
def countdown(i):
print i
if i <= 1: ## 기본 단계
return
else: ## 재귀 단계
countdown(i-1)
호출 스택은 프로그램의 중요 개념이다. 재귀를 사용할 때는 더 중요하다.
스택 stack : 푸시(push, 삽입)와 팝(pop, 빼내서 읽기) 두 동작만 가능한 자료구조.
컴퓨터가 함수에 사용되는 변수를 저장하는 스택을 콜 스택이라고 한다.
함수가 한 번 호출될 때 마다, 컴퓨터는 그 함수 호출에 필요한 메모리를 할당해 스택으로 쌓는다(push).
재귀 함수도 콜 스택을 사용한다.
아래는 팩토리얼 함수에 대한 재귀함수.
def fact(x):
if x == 1:
return 1
else:
return x * fact(x-1)
= 반복문에서 필요했던 상자 더미(pile
)의 역할.
재귀를 사용해 구현하면, 확인해야 할 상자 더미를 스택에 저장하는 것과 같다.
: 모든 정보를 컴퓨터 메모리에 저장해야 하므로 메모리를 많이 소비한다.
해결 1 : 재귀 대신 반복문으로 전환
해결 2 : 꼬리재귀 tail recursion 방법을 사용 - 고급 재귀 방법.