본문 바로가기

전공 깍두기/데이터 구조 조각

[데이터 구조] 3차시 순환(Recursion) | 모듈

1. 순환(recursion)

1) 정의: 자신을 정의할 때 자기 자신을 재참조하는 방법

2) 사용 형태: 프로그래밍에 적용한 "함수의 재귀 호출(Recursive call)"의 형태로 많이 사용

 

3) 재귀 호출(Recursive call)의 종류

(1) 직접 순환(direct call)

: 함수가 직접 자신(이름)을 호출

eg) A(A())

 

(2) 간접 순환(indirect call)

: 다른 제 3의 함수를 호출하고, 그 함수가 다시 자신(이름)을 호출

eg) A(B(A()))

 

 

4) 순환 방식의 적용

(1) 분할 정복(Divide and Conquer)의 특성을 가진 문제에 적합

  • 어떤 복잡한 문제를 간단하게 풀 수 있는 직접적인 작은 문제로 분할하여 해결하려는 방법
  • 분할된 문제가 원래의 큰 문제와 그 성질이 같은 경우에는, 분할된 문제의 푸는 방법도 동일

따라서, 1️⃣종료 조건이 만족할 때 까지 2️⃣변화된 입력을 받아 3️⃣같은 동작을 계속하며 순환함

 

 

5) 순환 함수의 명령문 골격

if(condition of simplest case) then solve directly
else make a recursive funsion call to a simpler case;

 

- 무한 루프를 돌지 않고 올바른 recursion을 하려면 아래가 모두 충족되어야 함

1️⃣ 함수 이름이 같아야 함
2️⃣ 인자가 감소/증가되는 부분이 있어야 함
3️⃣ 종료가 있어야 함

 

 

 

2. 순환 versus 반복

- 컴퓨터에서 같은 동작을 되풀이 하는 방법은 두 가지

  • 순환(recursion): 순환 함수를 반복 호출하는 법
  • 반복(iteration): for나 while을 이용한 반복하는 법
대부분의 순환은 반복으로 바꾸어 작성할 수 있다.⭐

 

 

1) 순환의 장단점

  • 순환적인 문제에서는 문제를 단순화한 자연스러운 방법임
  • 함수 호출의 오버헤드 있음

* 오버헤드란?

- 프로그램의 실행 흐름 도중에 동떨어진 위치의 코드를 실행시켜야 할 때, 추가적으로 시간/메모리/자원이 사용되는 현상

-  예상하지 못하는 자원들이 소모되는 현상

 

2) 반복의 장단점

  • 수행속도가 빠름
  • 순환적인 문제에 대해서는 프로그램 작성이 어려울 수 있음

 

 

3. 순환 함수의 예제 - Factorial Program

1) 비순환 함수 - 반복문 이용

int factorial(int n)
{
    if(n <= 1) return 1;
    else return n*factorial_n_1(n-1);
}

- 비순환 함수(for나 while 같은 반복 함수)로도 표현 가능

➡️ 표현이 조금 길지만 제어의 흐름이나 실행 과정을 쉽게 이해할 수 있음

 

- (n-1)!을 구하는 서브 함수 factorial_n_1를 따로 제작하는 경우의 프로그램

 

2) 순환 함수 - 재귀 호출

int factorial(int n)
{
    if(n <= 1) return 1;
    else return (n * factorial(n-1));
}

- (n-1)!을 현재 작성중인 함수를 같은 이름으로 다시 순환 호출하는 경우의 프로그램

 

 

 

4. 순환 함수의 예제 - 이원 탐색(binary search)

- 이원 탐색: 주어진 탐색키 key 값이 저장된 배열 a[]의 위치(인덱스, mid)를 찾아내는 방법

  • Problem: 서로 다른 n개의 정렬된 수가 배열에 저장되어 있을 때, 특정한 값을 찾아라
  • Specification of the binary search proble: 다음 배열 a[10]에서 "searchnum == 4"를 찾는 문제

middle에는 몫이 들어감

 

 

 

5. 순환 함수의 예제 - 비효율적인 경우

- 피보나치 수열(Fibonacci sequence): 각 항은 바로 직전 두 항의 합으로 만들어짐

eg) 0, 1, 1, 2, 3, 5, 8, 13, ...

 

=> 순환 호출 횟수가 급증하여 실행 시간을 기준으로 볼 때, 반복 함수(iteration function) 보다 비효율적임

=> 순환적 정의가 순환적 Algorithm으로 문제를 해결하는 데 최적의 방법이 아닐 수도 있다는 것을 보여주는 예제

 

 

6. 학습 내용 정리