// 1. num을 입력받으면 최초 num을 한 번 출력하고 1을 뺀 후 다시 countDown 함수를 호출한다.
// 2. 그럼 num - 1 값을 출력하고 다시 1을 뺀 후 다시 countDown 함수를 호출한다.
// 3. 위 과정을 계속 반복하다가 num이 0보다 작거나 같아지면 함수를 종료한다.
function countDown(num) {
// Base Case
if (num <= 0) {
console.log("Done!"); // Done!
// Recursive Case
} else {
console.log(num); // 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
num--;
countDown(num);
}
}
console.log(countDown(10));
sumTo(5)는 sumTo(4)에 5를 더하려고 하는데 sumTo(4)가 아직 계산이 되지 않아 값을 모르므로 콜 스택에 대기하고 있는다. sumTo(3), sumTo(2)도 마찬가지로 콜 스택에서 대기중인 상태이다.
sumTo(1)은 1을 반환하므로 재귀에서 탈출하게 된다. 그러고 나면 호출 스택에서 모든 값이 반대 순서로 합산되어 결과적으로 1부터 num까지의 합을 구하게 된다.
// 1. num을 입력받으면 입력받은 num값과 num - 1값을 더하는 과정을 num이 1이 될 때 까지 반복한다.
// 2.
function sumTo(num) {
// Base Case
if (num <= 1) { // num이 1보다 작거나 같을 때
return num; // 1
// Recursive Case
} else {
return num + sumTo(num - 1); // 55
}
};
function productOfArray(arr) {
// Base Case
if (arr.length === 1) {
return arr[0];
// Recursive Case
} else {
return arr[0] * productOfArray(arr.slice(1));
}
}
function factorial(num) {
// Base Case
if (num <= 1) {
return num;
// Recursive Case
} else {
return num * factorial(num - 1);
}
}
function fib(num) {
if (num <= 1) {
return num;
} else {
return fib(num - 2) + fib(num - 1);
}
}
Helper 메서드 재귀는 재귀적이지 않은 외부 함수가 재귀적인 내부 함수를 호출하는 패턴을 말한다.
result를 함수 안에 호출하고 재귀를 실행하면 재귀가 실행될 때 마다 result는 초기화 되기 때문에 값을 담을 수 없다. 따러서 재귀 함수 내에 또 하나의 helper 함수에 재귀를 실행시키고 result는 helper 함수 밖에 호출하여 초기화 되지 않고 result에 계속 데이터가 담기도록 한다.
function oddValue(arr) {
let result = [];
function helper(helperInput) {
// Base Case
if (helperInput.length === 0) {
return;
} else if (helperInput[0] % 2 !== 0) {
result.push(helperInput[0]);
}
// Recursive Case
helper(helperInput.slice(1));
}
// 처음 oddValue 함수가 호출되면 helper를 건너뛰고 바로 helper(arr)가 실행된다.
helper(arr);
return result;
}
console.log(oddValue([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // [1, 3, 5, 7, 9]
아래는 helper 메서드 재귀를 사용하지 않고 순수 재귀로만 구현한 동일한 함수다.
실행 과정은 아래와 같다. 아래의 과정을 arr.length가 0이 될 때까지 반복하다가 0이 되면 newArr에 구해놨던 배열을 역으로 다시 합친다.
function pureValue(arr) {
let newArr = [];
// Base Case
if (arr.length === 0) {
return newArr;
} else if (arr[0] % 2 !== 0) {
newArr.push(arr[0]);
}
// Recursive Case
newArr = newArr.concat(pureValue(arr.slice(1)));
return newArr;
}
console.log(pureValue([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); / [1, 3, 5, 7, 9]