삼삼고
꿈꾸는 삼삼고
삼삼고
전체 방문자
오늘
어제
  • 분류 전체보기 (179)
    • 후기 (95)
      • 코딩부트캠프 (90)
      • 취업 준비 기간 (5)
    • 백엔드 (20)
      • django (1)
      • 네트워크 (13)
      • 익스프레스 (0)
      • 그래프QL (2)
      • sqlite3 (1)
    • 프론트 엔드 (49)
      • javascript (21)
      • css (6)
      • react (8)
      • HTML (5)
      • UI&UX (8)
    • experience (1)
    • python (1)
    • project (1)
    • CS (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • django 첫걸음
  • http://www.tcpschool.com/ajax/ajax_basic_node
  • 코드스테이츠 세션 후기
  • 출처

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
삼삼고

꿈꾸는 삼삼고

[JavaScript]재귀
프론트 엔드/javascript

[JavaScript]재귀

2022. 10. 20. 21:53

❓재귀 함수(Recursion Function)란?

자기 자신을 다시 호출해 작업을 수행하는 방식이다.
아래의 코드를 보면 리턴 문을 사용해 rezero함수가 끝나기 전에 다시 함수를 호출해 주고 있다.
function rezero(){
console.log('무한반복중')
return rezero()
}
특정 분기까지 자기 자신을 계속해서 호출하는데, 주로 반복문을 구현할 때 사용한다.

 

이러한 제귀 함수의 가장 큰 사용 예제는 바로 팩토리얼이다.
(수학 시간에 배웠던 5!라는 문자를 생각해 봅시다....)
function factorial(num) { 
    if (num === 1) { 
        return 1; 
    } 
    //num이 1이 되었을때 함수 끝내기
    
    return num * factorial(num-1);
    //num값에 1씩 빼주면서 factorial함수를 다시 리턴해주고 그 값을 num에 곱해주는 방식이다
}
솔직히 나 스스로도 이해가 잘 되지 않는 식이다......(num이 두 개?...)
이를 좀 더 이해하기 쉽게 그림으로 해당 코드가 수행될 때의 콜 스택을 살펴보자.

👇만약 함수의 인자를 5로 넣을 경우......(5*4*3*2*1이 나오는 과정이다)

리턴하면서 하나씩 원래 값에서 분산시킨다고 생각하면 편할 겁니다.
5! === 5*4!
5! === 5*4*3!
5! === 5*4*3*2!
5! === 5*4*3*2*1
즉 계산하기 쉽게 축약된 식을 펼치는 것입니다.

 

❓Why we use Recursion Function

👌재귀 함수로 모든 반복문을 표현 가능하고 그 반대도 가능합니다.

❓그렇다면 재귀 함수는 왜 사용할까요? 이유는 바로 다음과 같습니다.
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);
                           }
                        }
                    }
                }
            }
        }
    }
 }
수많은 for문으로 인해 가독성이 떨어지고 for문 hell이 만들어진 것을 볼 수 있습니다.😫

👉재귀는 중첩된 반복문이 많거나 반복문의 중첩 횟수를 예측하기 어려운 경우 사용합니다.
앞으로 만나게 될 다양한 과제와 기업의 입사 시험(코딩 테스트, 알고리즘 테스트 등)이나 직무면접에서 활용할 수 있기 때문에, 기초를 확실하게 다져두는 게 바람직합니다.

 

 

 

❓How to use?

재귀 함수의 사용법은 문제를 어떻게 더 작게 쪼개는 가에 있습니다.
문제를 쪼개고 쪼갠 문제를 반복해서 쪼개게 되면 더 이상 쪼갤 수 없는 상태에 도달하게 됩니다.
그러면 비로소 가장 작은 단위의 문제를 해결합니다.
arrSum([]) === 0; // <-- 문제가 더는 작아지지 않는 순간
// 가장 작은 경우의 해결책을 적용합니다.
arrSum([5]) === 5 + arrSum([]) === 5 + 0 === 5;
arrSum([4, 5]) === 4 + arrSum([5]) === 4 + 5 === 9;
arrSum([3, 4, 5]) === 3 + arrSum([4, 5]) === 3 + 9 === 12;
arrSum([2, 3, 4, 5]) === 2 + arrSum([3, 4, 5]) === 2 + 12 === 14;
arrSum([1, 2, 3, 4, 5]) === 1 + arrSum([2, 3, 4, 5]) === 1 + 14 === 15;
arrSum 함수의 리턴 값이 나오면서 연쇄적으로 문제가 해결되고, 최종적으로는 문제 전체가 해결되는 것을 볼 수 있습니다.

 

📌분해하고 결합시키기

 

 

📌Case

재귀적으로 문제를 정리할 때는 base case와 Recursive case를 생각해야 한다.
  • base case(문제를 더 이상 쪼갤 수 없을 경우)
  //빈 배열의 경우
  if (arr의 길이가 0인 경우) {
    return 0;
  }
  
  //더이상 쪼갤수 없는 경우
   if (num<0)
    return 문제의 해답
  }
  • recursiv case(그렇지 않은 경우 문재가 더 쪼개질 경우)
  // recursive case : 그렇지 않은 경우
  return 더 작은 문제로 새롭게 정의된 문제
  }
  
  // recursive case : 그렇지 않은 경우
  return 요소1 + arrSum([요소2, ... , 요소n]);

 

 

❗주의할 점❗

재귀 함수는 무한 반복문으로 사용이 가능하기 때문에 무한 반복 시 에러가 발생할 수 있다.

 

Stack Overflow Error: 콜스택이 너무 많이 쌓여 한계점에 도달했을 때 에러가 발생한다.

Call Stack: 컴퓨터 프로그램에서 현재 실행 중인 서브루틴에 관한 정보를 저장하는 스택 자료구조
즉, 함수가 끝나면 다시 돌아올 위치를 기록해 두는 곳
함수를 재귀적으로 너무 많이 호출하게 되면 콜 스택이 계속해서 쌓이면서 더 이상 기록할 공간이 없어지게 됨 
=>  프로그램 중단
728x90
반응형
저작자표시 (새창열림)

'프론트 엔드 > javascript' 카테고리의 다른 글

Promise result값 사용하기  (2) 2023.01.13
[Javascript]Json  (0) 2022.10.21
[JavaScript]비동기 (Asynchoronous)  (0) 2022.10.02
[JavaScript] class의 상속  (0) 2022.09.25
[JavaScript]Prototype & Prototype chain  (0) 2022.09.24
    '프론트 엔드/javascript' 카테고리의 다른 글
    • Promise result값 사용하기
    • [Javascript]Json
    • [JavaScript]비동기 (Asynchoronous)
    • [JavaScript] class의 상속
    삼삼고
    삼삼고
    별이 되겠습니다

    티스토리툴바