Skip to content

Commit 469bade

Browse files
committed
docs: 알고리즘 실무 05
- 재귀 알고리즘에 대해 이해하고 학습합니다
1 parent 9ffc19a commit 469bade

File tree

1 file changed

+107
-0
lines changed
  • docs/알고리즘-실무

1 file changed

+107
-0
lines changed

docs/알고리즘-실무/05.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
sidebar_position: 8
3+
title: 재귀 알고리즘
4+
description: 재귀 알고리즘에 대해 이해하고 학습
5+
---
6+
7+
## 1. 재귀 알고리즘의 기본 개념
8+
9+
재귀(recursion)는 "함수가 정의될 때 자기 자신의 함수를 호출이 가능"하며, 이러한 자기 자신의 함수 호출을 **재귀 호출(recursive call)**이라고 합니다. 이는 **되부름 또는 순환**이라고도 표현됩니다. 재귀 알고리즘은 "어떤 사건이 자신을 다시 호출하여 작업을 수행하는 방식의 알고리즘"이며, 함수 형태로 많이 사용됩니다. 재귀를 효과적으로 사용하면 **프로그램을 간결하고 효율성 있게 작성**할 수 있습니다.
10+
11+
### 주요 특징
12+
13+
- **자기 참조적 특성:** 함수 내부에서 자기 자신의 함수를 호출합니다.
14+
- **문제 해결 용이성:** "재귀 함수를 이용하면 보다 쉽게 문제해결을 할 수 있"습니다.
15+
- **효율성 저하 가능성:** "계속적인 함수 호출로 인해 시간과 메모리 공간의 효율성이 떨어짐"이라는 단점이 있습니다.
16+
- **반복문 변환 가능성:** "일반적으로 반복문을 이용한 함수로 변환이 가능"합니다.
17+
18+
### 재귀 알고리즘의 속성 및 사용 방법
19+
20+
- **하위 문제 해결:** "어떤 사건을 해결하기 위해 사건의 범위보다 약간 좁은 하위 문제를 해결"합니다.
21+
- **종료 조건 필수:** "재귀 알고리즘의 호출은 더 이상 반복되지 않을 때까지 계속됨"으로, 종료 조건 설정이 중요합니다.
22+
- **구현 단계:**
23+
1. 반복되는 작업을 찾습니다.
24+
2. 반복되는 작업을 함수로 작성하고 입력값과 결과값의 형식을 결정합니다.
25+
3. "입력값은 한 단계씩 점진적으로 변하며, 마지막으로 더 이상 변화가 없는 입력값은 종료 조건으로 사용"됩니다.
26+
27+
### 재귀 알고리즘에 적합한 경우
28+
29+
- 풀어야 할 문제, 계산할 메서드, 처리할 자료구조가 재귀적으로 정의되는 경우에 적합합니다.
30+
31+
### 재귀의 종류
32+
33+
- **직접 재귀:** "자신과 동일한 메서드를 호출하는 것"을 의미합니다.
34+
- **간접 재귀:** "메서드 a가 메서드 b를 호출하고, 다시 메서드 b가 메서드 a를 호출하는 구조로 이루어지는 것"을 의미합니다. 즉, "다른 메서드를 통해 자기 자신과 같은 메서드를 호출"합니다.
35+
36+
---
37+
38+
## 2. 재귀 알고리즘의 적용 사례
39+
40+
### 2.1 팩토리얼(n!) 구하기
41+
42+
음이 아닌 정수 n의 팩토리얼은 재귀를 사용하여 구할 수 있는 대표적인 예시입니다.
43+
44+
- 0! = 1
45+
- n > 0이면 n! = n × (n - 1)!
46+
47+
**예시 코드 (TypeScript):**
48+
49+
```typescript
50+
function factorial(n: number): number {
51+
if (n > 0) return n * factorial(n - 1);
52+
else return 1;
53+
}
54+
```
55+
56+
위 코드는 n이 0보다 클 때 n \* factorial(n-1)을 반환하여 재귀적으로 호출하고, n이 0이 되면 1을 반환하여 재귀를 종료합니다.
57+
58+
### 2.2 유클리드 호제법 (최대공약수 구하기)
59+
60+
두 정수의 최대공약수를 재귀적으로 구하는 방법입니다. 이는 직사각형을 정사각형으로 채우는 비유로 설명됩니다. 짧은 변의 길이를 한 변으로 하는 정사각형으로 채운 후 남은 직사각형에 같은 작업을 반복하며, 최종적으로 정사각형만으로 구성되었을 때 변의 길이가 최대 공약수가 됩니다.
61+
62+
**최대공약수 계산 공식:**
63+
64+
- 정수 x, y의 최대 공약수를 구할 때:
65+
- y = 0일 때 최대 공약수는 x입니다.
66+
- y ≠ 0일 때 최대 공약수는 gcd(y, x % y)입니다.
67+
68+
**예시 코드 (TypeScript):**
69+
70+
```typescript
71+
function gcd(x: number, y: number): number {
72+
if (y === 0) return x;
73+
else return gcd(y, x % y);
74+
}
75+
```
76+
77+
---
78+
79+
## 3. 재귀 알고리즘 분석
80+
81+
재귀 알고리즘을 분석하는 방법에는 크게 두 가지가 있습니다.
82+
83+
### 3.1 하향식 분석 (Top-down analysis)
84+
85+
"메서드를 호출하는 것부터 시작하여 계단식으로 자세히 조사해 나가는 분석 기법"입니다. 예를 들어 recur(4)를 호출할 때, 호출이 발생한 순서대로 스택에 쌓이는 과정을 추적합니다.
86+
87+
### 3.2 상향식 분석 (Bottom-up analysis)
88+
89+
"아래쪽부터 쌓아 올리며 분석하는 방법"입니다. 이는 재귀 호출의 가장 낮은 단계부터 시작하여 결과가 어떻게 반환되고 쌓이는지 역으로 추적하는 방식입니다.
90+
91+
> 재귀 알고리즘은 **스택 구조로 저장되며, 종료된 후 마지막 값부터 pop되어 출력됨**을 이해하는 것이 중요합니다. 또한, **재함수를 작성할 때는 함수가 끝날 때까지 함수 호출 이후의 명령문이 실행되지 않**습니다.
92+
93+
---
94+
95+
## 4. 하노이의 탑: 재귀 알고리즘 구현의 대표적 예시
96+
97+
하노이의 탑은 재귀 알고리즘의 구현을 이해하는 데 매우 유용한 고전적인 문제입니다. 목표는 **쌓아둔 원반을 최소 횟수로 옮기**는 것입니다.
98+
99+
### 하노이의 탑 아이디어 (n개의 원반)
100+
101+
하노이의 탑 문제는 큰 원반을 먼저 옮기는 것이 아니라, 가장 큰 원반을 제외한 나머지 원반 그룹을 먼저 옮기는 방식으로 재귀적으로 해결됩니다.
102+
103+
1. 그룹을 시작 기둥에서 중간 기둥으로 옮깁니다. (가장 큰 원반을 제외한 n-1개의 원반)
104+
2. 바닥의 가장 큰 원반을 시작 기둥에서 목표 기둥으로 옮깁니다.
105+
3. 그룹을 중간 기둥에서 목표 기둥으로 옮깁니다. (중간 기둥으로 옮겨졌던 n-1개의 원반을 목표 기둥으로 최종 이동)
106+
107+
이러한 3단계 과정은 원반의 개수와 관계없이 동일하게 적용될 수 있습니다. move 메서드의 실행 과정을 통해 재귀 호출이 어떻게 단계적으로 진행되고 원반이 이동하는지 시각적으로 확인할 수 있습니다.

0 commit comments

Comments
 (0)