재귀(recursive) 알고리즘
알고리즘 및 자료구조 가이드
들어가며
지난 시간까지 우리는 빅오
, 알고리즘이란 무엇인가
, 간단한 문제 풀이 알고리즘
에 대해서 배워보았습니다.
이를 통해 알고리즘이란 무엇이며, 알고리즘이 컴퓨터에서 어떻 게 활용되는지에 대해서 감을 잡는 시간을 가졌습니다. 이렇게 익힌 감각을 바탕으로 이번 시간부터는 본격적으로 핵심 알고리즘들을 배우고, 이를 기반으로 해서 코딩 테스트 문제들을 몇 가지 풀면서 익히는 시간을 갖고자 합니다.
많은 알고리즘들 중에서 제일 먼저 배울 것은 재귀(Recursion)
입니다.
이는 재귀함수(Recursion)
이라고도 불립니다.
그러면 이게 무엇인지 같이 살펴봅시다.
재귀(Recursion)
그림으로 이해해보는 재귀

위의 그림을 한번 살펴봅시다.
어떤게 느껴지시나요? 계속 확대를 하고 있는데, 특정 패턴이 무한하게 반복되는게 느껴지시나요?
재귀의 대표적인 예시 중 하나인 프렉탈(fractal)입니다.
그림은 재귀의 핵심적인 요소를 명확히 보여주고 있는데 어떤 것인지 감이 잡히시나요?
재귀의 정의
먼저, 우리나라 사전에서는 재귀를 어떻게 정의하고 있는지 살펴볼까요?
원래의 자리로 되돌아가거나 되돌아옴.
- 표준대국어사전
유의어로는 귀소, 컴백이 있고, 예문으로는 "연어는 산란을 하기 위하여 태어났던 강으로 재귀한다" 라고 표시되어 있습니다.
일반적인 정의는 위와 같으나, 저희가 사용하는 재귀 혹은 재귀 함수에 사용하는 용어는 조금 다릅니다.
아래의 정의를 봅시다.
수학과 컴퓨터 과학에서 재귀적 정의 또는 귀납적 정의는 집합 내의 다른 원소를 통해 그 집합의 원소를 정의할 때 사용된다.
- 위키 백과 (Aczel, Peter(1977).《An Introduction to Inductive Definitions》
우리가 다루고자 하는 재귀는 위의 정의를 따릅니다.
재귀(Recursion)
라는 개념은 위에서 왔다고 봐도 무방합니다.
핵심은 "집합 내의 다른 원소를 통해서 그 집합의 원소를 정의할 때 사용된다." 입니다.
Recursionoccurs when the definition of a concept or process depends on a simpler or previous version of itself.
- wikipedia (Causey, Robert L. (2006).Logic, sets, and recursion
위키피디아에서 가져온 내용입니다. 재귀란 개념이나 과정을 정의할 때, 자기 자신의 이전이나 단순한 버전에 의존하는 것이라고 정의가 되어있습니다.
자기 자신의 이전 요소에 의존해서 어떤 개념이나 과정을 정의하는 것.
이게 곧 우리가 다룰 재귀의 전부입니다.
그림으로 다시 이해해보기
아래와 같이 선분이 있다고 해봅시다.

위와 같은 선분의 중앙에 삼각형을 배치한다고 생각을 해봅시다.

그러면 위와 같이 그려질 거에요. 여기에 다시 같은 작업을 해봅시다.

그러면 위와 같이 나타나게 됩니다.
이를 반복하면 어떻게 될까요?

위의 그림 처럼 나타나게 됩니다.
다시 말하면, 앞서 본 프렉탈의 규칙성을 "선분의 중앙에 삼각형을 배치 한다" 라고 표현할 수 있는 것이지요.
어떤가요? 프렉탈이 위와 같은 규칙성을 갖고 있다는게 이해가 되시나요?
그러면 이를 머리에 두고, 앞서 언급한 정의를 살펴봅시다.
재귀란 개념이나 과정을 정의할 때, 자기 자신의 이전이나 단순한 버전에 의존하는 것
이 말을 위의 그림에 맞춰볼까요?
- 개념이나 과정 :: 프렉탈
- 을 정의 :: 규칙성을 표현하라
- 자기 자신의 이전이나 단순한 버전 :: 선분의 중앙에 삼각형 하나를 그린 것
- 에 의존하는 것 :: 이를 반복하면 프렉탈이 완성
이해되시나요? 결국은 프렉탈을 구성하는 일부분(선분의 중앙에 삼각형 하나를 그린 것)을 통해서 프렉탈을 표현할 수 있었습니다.
이는 프렉탈을 구성하는 한 요소이기도 하지만, 한편으로는 규칙이기도 합니다.
이것이 재귀입니다.
알고리즘 관점의 재귀
앞서서 재귀의 개념에 대해 살펴보았습니다.
이번에는 재귀가 문제 해결에 어떻게 활용이 되는 지 살펴보고자 합니다.
팩토리얼 문제
Q. 1부터 n까지의 곱을 구하는 함수를 작성하시오.
재귀를 신경쓰지 않고 위의 문제를 한번 풀어보시겠어요?
단순한 풀이
위의 문제를 어떻게 풀 수 있을까요?
- 의사코드
- 코드
- n을 인자로 받는 multiply 함수를 선언한다.
- 함수 내부에 곱해진 값을 저장할 변수 result를 선언하고 1을 저장한다.
- n부터 1개씩 줄여가면서 1까지 n번 반복한다. 이때 반복인자 i를 선언한다. (i는 n부터 1까지 반복될 때의 값을 나타냄)
3-1. result * n을 하고, 이를 다시 result에 저장한다. - result를 반환한다.
function multiply(n) {
let result = 1;
for (let i = n; i >= 1; i--) {
result *= n;
}
return result;
}
제 나름대로 풀어봤어요.
이해가 되시나요??
이해가 안되어도 괜찮아요. 😄
같이 살펴보면서 하나씩 이해해봐요!