You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/알고리즘-실무/05.md
+81-8Lines changed: 81 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ description: 재귀 알고리즘에 대해 이해하고 학습
6
6
7
7
## 1. 재귀 알고리즘의 기본 개념
8
8
9
-
재귀(recursion)는 "함수가 정의될 때 자기 자신의 함수를 호출이 가능"하며, 이러한 자기 자신의 함수 호출을 **재귀 호출(recursive call)**이라고 합니다. 이는 **되부름 또는 순환**이라고도 표현됩니다. 재귀 알고리즘은 "어떤 사건이 자신을 다시 호출하여 작업을 수행하는 방식의 알고리즘"이며, 함수 형태로 많이 사용됩니다. 재귀를 효과적으로 사용하면 **프로그램을 간결하고 효율성 있게 작성**할 수 있습니다.
9
+
재귀(recursion)는 "함수가 정의될 때 자기 자신의 함수를 호출이 가능"하며, 이러한 자기 자신의 함수 호출을 **재귀 호출(recursive call)**이라고 합니다. 이는 **되부름 또는 순환**이라고도 표현됩니다. 재귀 알고리즘은 "어떤 사건이 자신을 다시 호출하여 작업을 수행하는 방식의 알고리즘"이며, 함수 형태로 많이 사용됩니다. 재귀를 효과적으로 사용하면 **프로그램을 간결하고 효율성 있게 작성**할 수 있습니다.
10
10
11
11
### 주요 특징
12
12
@@ -31,13 +31,38 @@ description: 재귀 알고리즘에 대해 이해하고 학습
31
31
### 재귀의 종류
32
32
33
33
-**직접 재귀:** "자신과 동일한 메서드를 호출하는 것"을 의미합니다.
34
+
35
+
```typescript
36
+
// 직접 재귀 예시
37
+
function directRecursion(n:number):number {
38
+
if (n<=0) return0;
39
+
returnn+directRecursion(n-1);
40
+
}
41
+
// directRecursion(3) → 3 + 2 + 1 + 0 = 6
42
+
```
43
+
34
44
-**간접 재귀:** "메서드 a가 메서드 b를 호출하고, 다시 메서드 b가 메서드 a를 호출하는 구조로 이루어지는 것"을 의미합니다. 즉, "다른 메서드를 통해 자기 자신과 같은 메서드를 호출"합니다.
35
45
46
+
```typescript
47
+
// 간접 재귀 예시
48
+
function indirectA(n:number):number {
49
+
if (n<=0) return0;
50
+
returnn+indirectB(n-1);
51
+
}
52
+
function indirectB(n:number):number {
53
+
if (n<=0) return0;
54
+
returnn+indirectA(n-2);
55
+
}
56
+
// indirectA(3) → 3 + indirectB(2)
57
+
// indirectB(2) → 2 + indirectA(0) → 2 + 0 = 2
58
+
// indirectA(3) → 3 + 2 = 5
59
+
```
60
+
36
61
---
37
62
38
63
## 2. 재귀 알고리즘의 적용 사례
39
64
40
-
### 2.1 팩토리얼(n!) 구하기
65
+
### 팩토리얼(n!) 구하기
41
66
42
67
음이 아닌 정수 n의 팩토리얼은 재귀를 사용하여 구할 수 있는 대표적인 예시입니다.
43
68
@@ -55,7 +80,7 @@ function factorial(n: number): number {
55
80
56
81
위 코드는 n이 0보다 클 때 n \* factorial(n-1)을 반환하여 재귀적으로 호출하고, n이 0이 되면 1을 반환하여 재귀를 종료합니다.
57
82
58
-
### 2.2 유클리드 호제법 (최대공약수 구하기)
83
+
### 유클리드 호제법 (최대공약수 구하기)
59
84
60
85
두 정수의 최대공약수를 재귀적으로 구하는 방법입니다. 이는 직사각형을 정사각형으로 채우는 비유로 설명됩니다. 짧은 변의 길이를 한 변으로 하는 정사각형으로 채운 후 남은 직사각형에 같은 작업을 반복하며, 최종적으로 정사각형만으로 구성되었을 때 변의 길이가 최대 공약수가 됩니다.
61
86
@@ -80,11 +105,11 @@ function gcd(x: number, y: number): number {
80
105
81
106
재귀 알고리즘을 분석하는 방법에는 크게 두 가지가 있습니다.
82
107
83
-
### 3.1 하향식 분석 (Top-down analysis)
108
+
### 하향식 분석 (Top-down analysis)
84
109
85
110
"메서드를 호출하는 것부터 시작하여 계단식으로 자세히 조사해 나가는 분석 기법"입니다. 예를 들어 recur(4)를 호출할 때, 호출이 발생한 순서대로 스택에 쌓이는 과정을 추적합니다.
86
111
87
-
### 3.2 상향식 분석 (Bottom-up analysis)
112
+
### 상향식 분석 (Bottom-up analysis)
88
113
89
114
"아래쪽부터 쌓아 올리며 분석하는 방법"입니다. 이는 재귀 호출의 가장 낮은 단계부터 시작하여 결과가 어떻게 반환되고 쌓이는지 역으로 추적하는 방식입니다.
90
115
@@ -100,8 +125,56 @@ function gcd(x: number, y: number): number {
100
125
101
126
하노이의 탑 문제는 큰 원반을 먼저 옮기는 것이 아니라, 가장 큰 원반을 제외한 나머지 원반 그룹을 먼저 옮기는 방식으로 재귀적으로 해결됩니다.
102
127
103
-
1. 그룹을 시작 기둥에서 중간 기둥으로 옮깁니다. (가장 큰 원반을 제외한 n-1개의 원반)
104
-
2. 바닥의 가장 큰 원반을 시작 기둥에서 목표 기둥으로 옮깁니다.
105
-
3. 그룹을 중간 기둥에서 목표 기둥으로 옮깁니다. (중간 기둥으로 옮겨졌던 n-1개의 원반을 목표 기둥으로 최종 이동)
128
+
```mermaid
129
+
flowchart TD
130
+
A[시작 기둥]
131
+
B[중간 기둥]
132
+
C[목표 기둥]
133
+
134
+
A -- "1단계: n-1개 원반 이동 (재귀)" --> B
135
+
A -- "2단계: 가장 큰 원반 이동" --> C
136
+
B -- "3단계: n-1개 원반 이동 (재귀)" --> C
137
+
```
138
+
139
+
#### 하노이의 탑 3단계 이동 시각화
140
+
141
+
-**1단계:** n-1개 원반을 시작 기둥(A)에서 중간 기둥(B)로 이동 (재귀 호출)
142
+
-**2단계:** 가장 큰 원반을 시작 기둥(A)에서 목표 기둥(C)로 이동
143
+
-**3단계:** n-1개 원반을 중간 기둥(B)에서 목표 기둥(C)로 이동 (재귀 호출)
106
144
107
145
이러한 3단계 과정은 원반의 개수와 관계없이 동일하게 적용될 수 있습니다. move 메서드의 실행 과정을 통해 재귀 호출이 어떻게 단계적으로 진행되고 원반이 이동하는지 시각적으로 확인할 수 있습니다.
0 commit comments