[(Programmers 강의) Algorithm with Data Structure 04강 ~ 05강. 재귀 알고리즘(Recursive Algorithms)]
재귀 알고리즘(Recursive Algorithms)
01. 재귀함수
-
재귀함수(Recursive Algorithm)란?
-
하나의 함수에서 자신을 다시 호출하여 작업을 수행하는 것
-
생각보다 많은 종류의 문제가 재귀적으로(recursively) 해결 가능
-
CS(Computer Science) 분야에서 자주 사용
- 이진 탐색과 비슷
- 이진 트리는 이진 탐색과 비슷한 흐름을 재귀적인 트리 알고리즘으로 구성
- 함수 내에서 자기 자신을 호출
-
# 자연수의 합 재귀 알고리즘(RecursionError)
def sum_num(n):
return n + sum_num(n - 1)
sum_num(10)
# Maximum recursion depth exceeded
# RecursionError
# 음수영역까지 끝없이 재귀하기 때문
def sum_num(n):
print(n) # 어떻게 실행되고 있는지 확인하기 위한 코드(디버깅)
return n + sum_num(n - 1)
sum_num(10)
10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 (중략) -2950 -2951 -2952 -2953 -2954
# 자연수의 합 재귀 알고리즘
def sum_num(n):
print(n)
if n <= 1:
return n
else:
return n + sum_num(n - 1)
sum_num(4)
4 3 2 1
10
-
재귀 호출의 종결 조건(trival case)
-
위 예제에서 확인했다 싶이 재귀 호출은 종결 조건(trival case)이 매우 중요
-
일반적 구조
def function(x): if n ...: ... # 매우 중요! else: ... function(...)
-
-
재귀 알고리즘의 효율
- 모든 재귀 알고리즘은 대칭되는(Counter-Part) 반복 알고리즘이 존재
- 시간복잡도 자체는 같으나 효율을 비교하면 다른 문제 - 위 예시의 효율성 - Reculsive Ver은 함수를 추가로 호출하는 부수적 동작 존재 - 따라서 Iterartive Ver보다 효율성이 떨어진다고 볼 수 있음 - 사람이 생각하는 방식을 표현하기에 유리하나 - 효율적인 측면에서 떨어질 수 있음(**조심해야할 부분**)
- 극단적인 예 : 상수시간의 알고리즘
-
생각보다 많은 문제가 재귀적으로 풀리긴 하지만
-
또, 재귀적으로 표현된 알고리즘이 사람이 이해하긴 좋지만
-
컴퓨터가 알고리즘 실행 시, 성능이 반드시 좋지는 않음
-
효율적인 측면에도 유념해야하기 때문에 알고리즘, 자료구조 선택이 중요
# 추가 예제(! - 팩토리얼)
def fac(n):
print(n)
if n <= 1: # trival case
return 1
else:
return n * fac(n - 1)
fac(5)
5 4 3 2 1
120
02. 과제 : Fibonacci 순열
-
Interative Ver VS Recursive Ver
- 둘 다 작성해볼것.
4강 연습문제(Link)
# Interative Ver
def solution(x):
l = [0, 1]
if x >= 2:
for i in range(2, x + 1):
l.append(l[i - 1] + l[i - 2])
return l[x]
solution(8)
21
# Recursive Ver
def solution(x):
if x == 0:
return 0
elif x <= 2 :
return 1
else:
return solution(x - 1) + solution(x - 2)
solution(8)
21
- 확실히 Interactive Version이 더 빠른 실행 결과로 통과했다.
# Recursive Ver
# 강사님 코드
def fibo(n):
if n <= 1:
return n
return fibo(n - 1) + fibo(n - 2)
fibo(8)
21
03. 재귀함수의 유용성
-
재귀 알고리즘을 통해 다음 문제 해결
-
조합의 수(n 개의 서로 다른 원소에서 m개를 택하는 경우의 수) 구하기
- 재귀적이지 않은 방법으로 해결
- 재귀적으로 방법으로 해결
- 잘못된 방법
- 올바른 방법
- 하지만 효율성 측면에서는 여전히 좋지 않다 - combi를 계속해서 호출하기 때문 - 그렇다면 왜 재귀함수를 쓸까?
-
-
하노이의 탑 문제
-
재귀 알고리즘이 효율은 떨어진다고 하더라도 사람이 생각하는 방식을 코드로 직접 옮김으로써 유용한 경우가 있다.
-
그 대표적 예가 이 문제
-
한 기둥의 원반들을 전부 다 다른 원반으로 옮기는 문제.
- 단, 더 큰 원반은 더 작은 원반의 위로 올라갈 수 없음
-
이 문제를 재귀적 알고리즘을 통해 해결하면 편함.
- 나중에 한 번 해볼것!
-
# 하노이의 탑 도전(작성 예정)
-
아주 많은 자료구조에 있는 문제 中 트리에 해당하는 문제는 재귀 알고리즘으로 푸는게 적당할 수 있음
- 연습문제(빈칸채우기) : 재귀적 이진 탐색
04. 과제 2
5강 연습문제(Link)
def solution(L, x, l, u):
if x < L[l] or x > L[u]:
return -1
mid = (l + u) // 2
if x == L[mid]:
return mid
elif x < L[mid]:
return solution(L, x, l, mid - 1)
else:
return solution(L, x, mid + 1, u)
댓글남기기