본문 바로가기
자료구조

#05 재귀- 하노이탑

by chunkind 2024. 3. 27.
반응형

하노이 탑(Tower of Hanoi) 알고리즘 이해하기

하노이 탑(Tower of Hanoi)은 수학적 퍼즐로, 세 개의 막대와 여러 개의 크기가 다른 원판으로 구성됩니다. 퍼즐의 목표는 한 막대에 쌓여 있는 원판들을 다른 막대로 옮기는 것입니다. 이 과정에서 다음 규칙을 준수해야 합니다:

  1. 한 번에 하나의 원판만 옮길 수 있습니다.
  2. 원판은 항상 큰 원판이 작은 원판 아래에 위치하도록 옮겨야 합니다.
  3. 세 번째 막대를 이용하여 중간 과정을 거칠 수 있습니다.

하노이 탑 알고리즘 구현

하노이 탑 문제를 해결하기 위해 재귀 알고리즘을 사용합니다. 다음은 C 언어로 구현한 예제 코드입니다:

#include <stdio.h>

void Hanoi(int num, char from, char by, char to) {
    if (num == 0)
        return;
    Hanoi(num - 1, from, to, by);
    printf("%d을 %c에서 %c로 이동\n", num, from, to);
    Hanoi(num - 1, by, from, to);
}

int main() {
    Hanoi(4, 'A', 'B', 'C');
    return 0;
}

위 코드에서 Hanoi 함수는 재귀적으로 호출되어 원판을 옮기는 과정을 출력합니다. main 함수에서 Hanoi(4, 'A', 'B', 'C')를 호출하면 4개의 원판을 'A' 막대에서 'C' 막대로 옮기는 과정을 출력합니다.

하노이 탑의 작동 과정

하노이 탑 알고리즘의 재귀 호출 과정은 다음과 같이 표현할 수 있습니다:

  1. Hanoi(4, 'A', 'B', 'C') 호출
    • Hanoi(3, 'A', 'C', 'B') 호출
      • Hanoi(2, 'A', 'B', 'C') 호출
        • Hanoi(1, 'A', 'C', 'B') 호출
          • Hanoi(0, 'A', 'B', 'C') 반환
          • 1을 A에서 C로 이동 출력
          • Hanoi(0, 'B', 'A', 'C') 반환
        • Hanoi(1, 'C', 'A', 'B') 호출
          • Hanoi(0, 'C', 'B', 'A') 반환
          • 1을 C에서 B로 이동 출력
          • Hanoi(0, 'A', 'C', 'B') 반환
      • Hanoi(2, 'B', 'C', 'A') 호출
        • Hanoi(1, 'B', 'A', 'C') 호출
          • Hanoi(0, 'B', 'C', 'A') 반환
          • 1을 B에서 A로 이동 출력
          • Hanoi(0, 'C', 'B', 'A') 반환
        • Hanoi(1, 'A', 'C', 'B') 호출
          • Hanoi(0, 'A', 'B', 'C') 반환
          • 1을 A에서 B로 이동 출력
          • Hanoi(0, 'C', 'A', 'B') 반환

...

                                       Ha(3,'A','B','C')  
              Ha(2,'A','C','B')                          Ha(2,'B','A','C')  
Ha(1,'A','B','C')  Ha(1,'C','A','B')  Ha(1,'B','C','A')  Ha(1,'A','B','C')

                                                                                   Ha(4,'A','B','C')  
                                      Ha(3,'A','C','B')                                                                         Ha(3,'B','A','C')  
            Ha(2,'A','B','C')                           Ha(2,'B','C','A')                        Ha(2,'B','C','A')                           Ha(2,'C','A','B')  
Ha(1,'A','C','B') Ha(1,'C','B','A') Ha(1,'B','A','C') Ha(1,'A','C','B') Ha(1,'B','A','C') Ha(1,'A','C','B') Ha(1,'C','B','A') Ha(1,'B','A','C')

하노이 탑의 재귀적 분할

하노이 탑 문제를 해결하기 위해, 문제를 세 부분으로 나눕니다:

  1. n-1개의 원판을 출발지 막대에서 보조 막대로 이동
  2. 가장 큰 원판을 출발지 막대에서 목적지 막대로 이동
  3. n-1개의 원판을 보조 막대에서 목적지 막대로 이동

이러한 접근 방법을 통해 문제를 단순화하고, 재귀적으로 해결할 수 있습니다.

하노이 탑의 시간 복잡도

하노이 탑의 시간 복잡도는 원판의 수에 대해 지수적으로 증가합니다. 정확히는, 시간 복잡도는 (O(2^n - 1))입니다. 이는 원판의 수가 하나씩 증가할 때마다 필요한 이동 횟수가 두 배로 증가함을 의미합니다.

이와 같이 하노이 탑 문제는 재귀 호출과 분할 정복 알고리즘의 좋은 예시이며, 컴퓨터 과학에서 중요한 개념을 배우는 데 유용합니다.


하노이 탑 알고리즘은 그 자체로도 흥미롭지만, 재귀와 분할 정복의 원리를 이해하는 데 큰 도움이 됩니다. 특히 알고리즘을 처음 배우는 사람들이라면, 이 퍼즐을 통해 재귀적 사고를 기를 수 있습니다.

여러분도 직접 코드를 작성해보고 실행해 보면서 하노이 탑 알고리즘을 이해해 보세요. 재귀 호출의 원리를 시각적으로 확인할 수 있어 큰 도움이 될 것입니다.

반응형