본문 바로가기

[자료구조론] 2주차: 순환

순환(Recursion)

정의 자체가 순환적인 경우 적합하다.

주어진 문제를 더 작은 동일한 문제로 분할해 해결(분할 정복: Divide and Conquer)

 

Ex) Factorial

$n!$은 $n \geq 1$에 대해서는 $n(n-1)!$, $n = 0$에 대해서는 1로 정의할 수 있다.

1
2
3
4
int factorial(int n)
{
    return (n <= 1) ? 1 : (n * factorial(n - 1));
}
cs

$n!$

$= n \times (n - 1)!$

$= n \times (n - 1) \times (n - 2)!$

$\cdots$

$= n \times (n - 1) \times (n - 2)! \times \cdots \times 2!$

$= n \times (n - 1) \times (n - 2)! \times \cdots \times 2 \times 1!$

$= n \times (n - 1) \times (n - 2)! \times \cdots \times 2 \times 1$

 

Divide and conquer

$n \times (n - 1)!$에서 $n$은 이미 해결된 부분, $(n - 1)!$은 남아 있는 부분(더 작은 동일한 문제)

 

* 순환 알고리즘에는 반드시 순환을 멈추는 부분이 필요하다. 안 그러면 무한 호출돼서 메모리 터짐

* 대부분의 순환은 반복(iteration)으로 바꾸어 작성할 수 있다.

 

 

팩토리얼을 반복으로 구현하면 다음과 같다.

1
2
3
4
5
6
7
8
int factorial_iter(int n)
{
    int result = 1, i;
 
    for (i = 1; i <= n; result *= i++);
 
    return result;
}
cs

 

Recursion VS Iteration

시간 복잡도: 둘 다 $O(n)$

공간 복잡도: 순환은 함수 호출 오버헤드, 반복은 오버헤드가 적다.

-> 왜 순환인가?: 간결한 코드, 반복으로 표현하기 어려운 순환도 있음

 

 

Ex2) Power by recursion

$\begin{cases}(x^2)^{\frac{n}{2}} & n\;is\;even\\x(x^2)^{\frac{n-1}{2}} & n\;is\;odd\end{cases}$

 

- $2^{10}$

$2^{10} = (2^2)^{\frac{10}{2}}=(2^2)^5$

$4^5 = 4 \times 4^4 = 4 \times ((4^2)^{\frac{4}{2}}) = 4 \times 16^2$

$16^2 = (16^2)^1$

$256^1 = 256^1 \times (256^2)^0 = 256 \times 65536^0$

$65536^0 = 1$

 

반복의 경우 $x^n$을 구하려면 대략 $n$번의 계산 필요 -> $O(n)$

순환의 경우 대략 $x^n$에 대해 $n=2^k$라 하면 $k$번의 계산 필요

즉 $\log_{2}{n}$번의 연산을 요하므로  $O(\log{n})$

1
2
3
4
5
6
7
8
9
10
int power(int x, int n)
{
    if (n == 0)
        return 1;
    else
    {
        return (n % 2 == 0) ? power(x * x, n / 2)
                            : x * power(x * x, (n - 1/ 2);
    }
}
cs

$cf.$ $x\;*\;x$ 대신 $power(x, 2)$를 쓰면 $power(2, 2)$가 무한히 호출됨

 

 

 

 

 

 

 

'강의노트 > 자료구조론' 카테고리의 다른 글

[자료구조론] 2주차: Notation  (0) 2021.03.14
[자료구조론] 1주차  (0) 2021.03.12