앞서 재귀함수란 특정 조건이 만족할 때까지 자기 자신을 호출하는 함수를 뜻한다는 것을 알았다.
즉 자기가 호출하고 자기가 응답하는 셈이다.
이번 시간엔 재귀함수의 조건과 재귀함수를 왜 그리고 언제 사용해야 하는지, 재귀함수의 주의점, 그리고 대표적인 재귀함수 예제에 대해 알아보자.
이 글은 JavaScript 알고리즘 & 자료구조 마스터클래스를 참고하여 작성되었습니다.
재귀 함수는 특정 조건을 만족할 때까지 스스로를 계속 호출하기 때문에 반드시 탈출 조건이 필요하다.
매 재귀함수를 호출할 때마다 다른 매개변수를 전달해야 한다. 매번 같은 매개변수 값을 전달하는 것은 같은 작업을 무한 번 반복하는 셈이기 때문이다.
모든 재귀 함수는 동일한 작은 단위의 처리를 반복해서 처리하기 때문에 for문
이나 while문
으로도 충분히 표현 가능하다. 그런데도 왜 재귀함수를 써야 할까?
→ 재귀함수를 사용하면 보다 간결하고 가독성 좋은 코드 작성이 가능하다는 장점이 있다.
재귀함수로 작성할 때
function arrSum(arr) {
if(arr.length === 0) {
return 0
}
return arr.shift() + arrSum(arr);
}
for문으로 작성할 때
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
for (let k = 0; k < n; k++) {
for (let l = 0; l < n; l++) {
for (let m = 0; m < n; m++) {
for (let n = 0; n < n; n++) {
for (let o = 0; o < n; o++) {
for (let p = 0; p < n; p++) {
// do something
someFunc(i, j, k, l, m, n, o, p);
}
}
}
}
}
}
}
}
Math.pow()
을 모방하여 두 개의 수를 변수로 받아 첫 번째 수는 밑, 두 번째 수는 지수가 되어 밑의 거듭제곱을 지수로 반환하는 함수
function power(base, exponent) {
if (exponent === 0) return 1;
return base * power(base, exponent - 1);
}
console.log(power(2, 2)); // 4
console.log(power(2, 0)); // 1
console.log(power(2, 4)); // 16
- power 함수는
밑 * power 함수
를 한 값을 리턴한다.- 재귀 함수인 power의 인자로는 base와 exponent-1한 값이 연속적으로 주어지며, 탈출 조건은 exponent가 0이 될 때로, 이때 1을 리턴한다.
숫자를 받아 해당 숫자의 계승(팩토리얼)을 반환하는 팩토리얼 함수
function factorial(n) {
if (n === 1 || n === 0) return 1;
return n * factorial(n - 1);
}
console.log(factorial(2)); // 2
console.log(factorial(4)); // 24
console.log(factorial(7)); // 5040
- factorial 함수는
n * factorial 함수
를 한 값을 리턴한다.- 재귀 함수인 factorial의 인자로는 n-1한 값이 연속적으로 주어지며, 탈출조건은 n이 1 또는 0일 때이다.
숫자 배열을 받아 모든 숫자의 곱을 반환하는 함수
function productOfArray(arr) {
if (arr.length === 0) return 1;
return arr[0] * productOfArray(arr.slice(1));
}
console.log(productOfArray([1, 2, 3])); // 6
console.log(productOfArray([1, 2, 3, 10])); // 60
- productOfArray는
arr의 첫번째 요소 * productOfArray 함수
값을 리턴한다.- 재귀 함수인 productOfArray의 인자로는 arr의 0번째 요소를 제외한 값이 연속적으로 주어지며, 탈출 조건은 해당 배열의 길이가 0이 될 때이다.
0부터 전달된 숫자까지의 모든 합을 더하는 함수
function recursiveRange(n) {
if (n === 0) return 0;
return n + recursiveRange(n - 1);
}
console.log(recursiveRange(6)); // 21
console.log(recursiveRange(10)); // 55
- recursiveRange는
n + recursiveRange
값을 리턴한다.- 재귀함수인 recursiveRange의 인자로는 n-1한 값이 연속적으로 주어지며, 탈출조건은 n이 0이 될 때이다.
숫자를 받아 피보나치 수열의 n번째 숫자를 반환하는 함수
function fib(n) {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2);
}
console.log(fib(4)); // 3
console.log(fib(10)); // 55
console.log(fib(28)); // 317811
console.log(fib(35)); // 9227465
fib는
fib(n - 1) + fib(n - 2)
값을 리턴하며 탈출 조건은 n이 2와 같거나 작을 때이다.