[재귀함수]
재귀 함수에 대하여 알아보자!
<STUDY>
재귀 함수 (Recursion Function)
자기 자신을 호출하는 함수
- 함수 내부에서 자기 자신을 호출함
💡 재귀 사용 이유
모든 곳에서 사용되기 때문!
❓재귀 함수가 자기 자신을 계속 호출한다면?
- 함수 호출시 호출 스택 위에 함수가 쌓임
- 반환 키워드를 확인하거나, 함수 안에 더이상 실행할 코드가 없는 경우 컴파일러가 호출 스택 가장 위에 있는 항목을 제거함
💡 호출 스택
함수가 올바른 순서대로 실행되도록 하는 자바스크립트의 정적 데이터 구조 (보이지 않는 곳에서 작동함!)
예시
function takeShower() {
return "Showering!"
}
function eatBreakfast() {
let meal = cookFood();
return `Eating ${meal}`;
}
function cookFood() {
let items = ["Oatmeal", "Eggs", "Protein Shake"];
return items[Math.floor(Math.random()*items.length)];
}
function wakeUp() {
takeShower();
eatBreakfast();
console.log("Ok ready to go to work!");
}
wakeUp();
# 호출 스택
[wakeUp] → [wakeUp, takeShower] → [wakeUp, eatBreakfast] → [wakeUp, eatBreakfast, cookFood] → [wakeUp, eatBreakfast] → [wakeUp] → []
재귀 함수 조건
- 다른 입력값
- 중단점 (종료 지점) 필요! (라인을 끝내는 종료 조건) ⇒ 종료 조건에서 반환문이 필요함
## 예시
- 입력된 값에서 1까지 연속적으로 출력하는 함수
function countDown(num) {
if (num <= 0) {
console.log("All done!");
return;
}
console.log(num);
num--;
countDown(num);
}
countDown(5); // 5 4 3 2 1 All done!
# 호출 스택
[countDown(5)] → [countDown(4)] → [countDown(3)] → [countDown(2)] → [countDown(1)] → [countDown(0)]
- 팩토리얼
- 반복문
function factorial(num) {
let total = 1;
for (let i = num; i > 0; i--) {
total *= i;
}
return total;
}
factorial(4); // 24
- 재귀 호출
function factorial(num) {
if (num === 1) return 1;
return num * factorial(num - 1);
}
factorial(4); // 24
# 호출 스택
[4 * facorial(3)] → [4 * factorial(3), 3 * facorial(2)] → [4 * factorial(3), 3 * facorial(2), 2 * factorial(1)] → [4 * factorial(3), 3 * facorial(2), 2 * factorial(1), return 1] → [4 * factorial(3), 3 * facorial(2), 2 * factorial(1)] → [4 * factorial(3), 3 * facorial(2)] → [4 * factorial(3)] → []
재귀 함수의 위험성
- 종료 조건이 없거나 잘못되는 경우 - 스택 오버플로 (stack overflow)⇒ 종료 조건에 반환문이 없는 경우 (return X)
- ⇒ factorial 예시에서 0이나 음수를 입력하는 경우
헬퍼 메소드 재귀 (헬퍼 함수)
외부 함수 안에서 정의되고 호출되는 재귀 함수
- 배열이나 데이터 목록 등을 컴파일할 때 사용하는 방법
## 예시 - 홀수 찾기
- 방법 1
function collectOdds(nums) {
let result = [];
function helper(helperInput) {
if (helperInput.length === 0) return;
if (helperInput[0] % 2 !== 0) result.push(helperInput[0]);
helper(helperInput.slice(1));
}
helper(arr);
return result;
}
collectOdds([1,2,3,4,5,6,7,8,9]); // [1,3,5,7,9]
- 방법 2
function collectOddValues(arr){
let newArr = [];
if (arr.length === 0) return newArr;
if (arr[0] % 2 !== 0) newArr.push(arr[0]);
newArr = newArr.concat(collectOddValues(arr.slice(1)));
return newArr;
}
collectOddValues([1,2,3,4,5]);
알고리즘을 공부하면서 재귀 함수에 대한 이해가 부족하다는 생각이 많이 들어 정리해 보았다.
앞으로 조금 더 차근차근 공부해 나가야 할 것 같다.
'STUDY > Algorithm' 카테고리의 다른 글
정렬 알고리즘 (Sorting Algorithm) / 버블 정렬, 선택 정렬, 삽입 정렬, 합병 정렬, 퀵 정렬, 기수 정렬 (2) | 2023.04.07 |
---|---|
탐색 알고리즘 (Search Algorithm) / 선형 탐색, 이진 탐색 (0) | 2023.04.02 |
[프로그래머스_자바스크립트] Lv.2 당구 연습 / math, 좌표 이동, 대칭 (2) | 2023.03.21 |
[프로그래머스_자바스크립트] Lv.1 포켓몬 / 해시 (Hash) (0) | 2023.01.26 |
[프로그래머스_자바스크립트] Lv.1 숫자 짝꿍 / 해시 알고리즘 (0) | 2023.01.23 |