본문 바로가기
자료구조

[자료구조] 순환, 히노이탑

by 유일리 2022. 10. 18.
순환이란?

 

알고리즘이나 함수가 수행 도중에 자기 자신을 다시 호출하여 문제를 해결하는 기법이다.

순환 알고리즘은 다음과 같은 부분들을 포함한다.

  • 순환 호출을 하는 부분
  • 순환 호출을 멈추는 부분

만약 순환 호출을 멈추는 부분이 없다면? 시스템 오류가 발생할 때까지 무한정 호출하게 된다.

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

 

순환적인 방법이 더 효율적인 예제

숫자 x n제곱 값을 구하는 문제: x^n

  • 반복
double slow_power(double x, int n)
{
	int i;
	double result = 1.0;
	for(i=0; i<n; i++)
		result = result * x;
	return(result);
}
  • 순환
double power(double x, int n)
{
	if( n==0 ) return 1;
	else if ( (n%2)==0 ) 
		return power(x*x, n/2);
	else return x*power(x*x, (n-1)/2);
}

순환 호출을 사용하면 비효율적인 예

피보나치 수열

순환 호출을 사용했을 경우의 비효율성 

  • 같은 항이 중복해서 계산됨
  • 예를 들어 fib(6) 호출하게 되면 fib(3) 4번이나 중복되어서 계산됨
  • 이러한 현상은 n 커지면 심해짐

히노이탑

문제
  • 문제는 막대 A 쌓여있는 원판 n개를 막대 C 옮기는 것이다.
  •  번에 하나의 원판만 이동할  있다.
  • 위에 있는 원판만 이동할 있다.
  • 크기가 작은 원판 위에  원판이 쌓일  없다.
  • 중간의 막대를 임시적으로 이용할 있으나 앞의 조건들을 지켜야 한다.

- n=3일 때

- 일반적인 경우

- n=4일 때

#include <stdio.h>
void hanoi_tower(int n, char from, char tmp, char to)
{
  if( n==1 ) printf("원판 1을 %c 에서 %c으로 옮긴다.\n",from,to);
    else {
	hanoi_tower(n-1, from, to, tmp);
	printf("원판 %d을 %c에서 %c으로 옮긴다.\n",n, from, to);
	hanoi_tower(n-1, tmp, from, to);
  }
}
int main(void)
{
    hanoi_tower(4, 'A', 'B', 'C');
    retrun 0;
}

 

히노이탑 시간 복잡도 분석

순환적 알고리즘 방정식:     T(n)=2T(n-1)+1     ..…………….

 귀납적 추론에 의해 다음 방적식이 성립한다.

        T(n-1)=2T(n-2)+1     ……………....

        T(n-2)=2T(n-3)+1     ……………....

 식의 T(n-2)③식을 대입하자.

        T(n-1)=2(2T(n-3)+1)+1  …………….

 ① T(n-1)④식을 대입하자.

        T(n)=2(2(2T(n-3)+1)+1)+1

이 식을 일반화시켜보면, 특정숫자 3대신 k로 풀어볼 수 있다.

우리가 알고 있는 수렴조건(기초 단계)T(1)=1 T(n-k) 에 대입한다면,

        n-k=1

        k=n-1

G.P.(Geometric Progression) 수열의 합으로써  (2^n)-1답이다.

그러므로 우리는 알고리즘의 시간복잡도는 O(2^n) 라고 말할 있다.

한 예로, 원판갯수 n=5 라면, 총이동 횟수는 2^5-1 = 31번이 걸린다.  

 

'자료구조' 카테고리의 다른 글

[자료구조] 큐(Queue)  (0) 2022.10.19
[자료구조] 스택(Stack) 예제  (0) 2022.10.19
[자료구조] 스택(Stack)  (0) 2022.10.19
[자료구조] 배열 구조체 포인터  (0) 2022.10.18
[자료구조] 자료구조와 알고리즘  (0) 2022.10.18

댓글