Recursion 을 작은조각으로 쪼개고 문제 하나를 풀고 , 또 다시 작은 조각으로 나누고 문제 하나를 푸는 방식으로 이해하면 된다.
-
Recursion 의 정의와 어떻게 활용할 수 있는지 알아보자
-
재귀 함수에 가장 중요한 두가지 요소를 이해하자
-
콜 스택을 시각화 해서 디버깅과 재귀함수를 더 잘 이해하자
-
helper method recursion과 순수한 재귀를 사용해서 다양한 문제를 해결해보자
A process (a function in our case) that calls itslef
- JSON.parse / JSON.stringfy 함수에서 재귀를 사용한다.
- document.getElementById and DOM 순회 algorithms
- Object 순회
- 이후에 복잡한 자료구조에서 재귀를 사용할 것이다.
- 가끔은 깔끔하게 하기 위해 반복문 대신에 사용할 수 도 있다.
자 이제 함수부터 이야기 해보자~
- 대두분의 프로그래밍 언어에는 함수 실행될 때 자료구조를 만드는 콜스택이 있다.
- call stack 은 스택 자료구조 이다.
- 함수를 불러올 때 마다 함수를 맨 위에 위치시킨다.
- 자바스크립트에서
return이나 함수가 끝날때 컴파일러는 맨 위에 것을 제거한다.
- 함수가 콜스택에 올라가고 완료되면 제거된다.
- 재귀 함수를 작성하면 계속해서 새로운 함수를 콜스택에 올린다.
Invoke the same function with a different input until you reach you base case!
The condition when the recursion ends.
- Base Case
- Different Input
function countDown(num) {
if(num <= 0) {
console.log("All done!");
return;
}
console.log(num);
num--;
countDown(num);
}function sumRange (num) {
if(num ===1) return 1;
return num + sumRange(num-1)
}// 반복문
function factorial(num) {
let total = 1;
for(let i = num; i > 0; i--) {
total *= i
}
return total;
}
// 재귀
function factorial1(num) {
if(num ===1) return 1
return num * factorial(num-1)
}-
No base case (끝나는 지점이 없을 때)
-
return을 깜박하거나 잘못된 것을return할 때 -
Stack Overflow
function factorial (num) { if (num === 1) return 1; return num * factorial(num); // return wrong thing }
function factorial (num) { if (num === 1) console.log(1); //no basic case return num * factorial(num-1); }
-
Example Let's try to collect all of the odd values in an array!
function collectOddValues(arr) { let result = [] function helper(helperInput) { // basic case if(helperInput.length === 0) { return } if(helperInput[0] % 2 !== 0){ result.push(helperInput[0]) } helper(helperInput.slice(1)) } helper(arr) return result; }
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;
}- slice, the spread operator , concat 메소드는 원래 배열을 바꾸지 않는다.
- string은 변경 할 수 없기 때문에 slice, substr, substring 메소드를 사용하자
- 객체를 복사하기 위해 Objec.assign, the spread operator를 사용하자
- 배열을 만질 때는 return에
concat가 자주 나온다