재귀 알고리즘 9- 복잡한 재귀의 하노이 타워 문제

 

하노이 탑 문제는 인도의 고대 전설에서 파생되었습니다. 하나님 께서 세상을 창조하실 때 다이아몬드 기둥 3 개를 만드셨는데, 하나의 기둥에 64 개의 금속 원반이 위에서 아래로 쌓여 있습니다. 하나님은 브라만에게 디스크를 아래에서 크기 순서대로 다른 기둥에 다시 놓으라고 명령하셨습니다. 또한 작은 디스크에서는 디스크를 확장 할 수 없으며 세 기둥 사이에서 하나의 디스크 만 이동할 수 있다고 규정합니다.

[분석]
이 문제는 실제로 n 개의 디스크를 기둥 A에서 기둥 C로 이동시키는 것입니다. 기둥 B는 이동 중에 사용할 수 있습니다. 한 번에 하나의 디스크 만 이동할 수 있으며, 큰 디스크는 항상 아래에 있고 작은 원은 디스크.

기둥 B를 사용하여 n 개의 디스크를 기둥 A에서 C로 이동하려면 먼저 기둥 A에서 기둥 C를 사용하여 위의 n-1 디스크를 B로 이동 한 다음 n 번째 디스크를 직접 기둥 C의 상단으로 이동합니다. 그런 다음 기둥 A의 도움으로 기둥 B에서 n-1 디스크를 C로 이동하여 n 문제를 n-1 문제로 분해합니다.

이런 식으로 n 개의 플레이트를 기둥 A에서 기둥 C로 이동할 수 있지만 아직 해결되지 않은 문제가 있습니다. 즉, n-1 디스크를 A에서 B로 이동 한 다음 B에서 기둥으로 이동하는 방법입니다. 기둥 C.

기둥 A에서 기둥 B로 n-1 디스크를 이동하려면 위의 n-2 디스크를 흡수하여 B의 도움으로 기둥 A에서 기둥 C로 이동 한 다음 n-1 디스크를 B로 직접 이동해야합니다. A는 n-2 개의 디스크를 C에서 B로 이동합니다.

n-1 디스크를 B 열에서 C 열로 이동하려면 재귀가 필요합니다. 디스크를 이동하는 과정은 재귀의 특성과 일치합니다. 큰 문제는 작은 문제로 축소됩니다. 재귀의 끝 조건은 한 번에 하나의 플레이트 만 이동하는 것입니다. 그렇지 않으면 재귀가 계속됩니다.

문제를 단순화하기 위해 B를 사용하여 A 열에서 C 열로 세 개의 디스크를 이동하는 과정을 분석해 보겠습니다.

(1) A 열의 디스크 두 개를 B 열로 이동합니다 (C 열의 도움으로).
(2) A 열의 디스크를 C 열 (A-> C)로 직접 이동합니다.
(3) B 열의 디스크 두 개를 C 열로 이동합니다 (A 열의 도움으로).

이 중 (2) 단계는 직접 구현할 수 있으며, (1) 단계는 계속해서 분해 할 수 있습니다.

A 열의 디스크를 C 열 (A-> C)로 직접 이동합니다.
b. A 열의 디스크를 B 열로 직접 이동합니다 (A-> B).
c. C 열의 디스크를 B 열로 직접 이동합니다 (C-> B).

단계 (3)은 계속 분해 할 수 있습니다.

B 열의 디스크를 A 열로 직접 이동합니다 (B-> A).
b. B 열의 디스크를 C 열 (B-> C)로 직접 이동합니다.
c. A 열의 디스크를 C 열 (A-> C)로 직접 이동합니다.

A-> C , A-> B , C-> B , B-> A , B-> C , A-> C

암호:

#include<stdio.h>
#include <iostream>
void hanoi(int n, char one, char two, char three);
void move(char x, char y);
void main()
{
	int n;
	printf("请输入圆盘的个数:");
	scanf("%d", &n);
	printf("移动步骤如下:\n");
	hanoi(n, 'A', 'B', 'C');
	system("pause");
}
void move(char x, char y)
{
	printf("%c-->%c\n", x, y);
}
void hanoi(int n, char one, char two, char three)
{
	if (n == 1)
		move(one, three);
	else
	{
		hanoi(n - 1, one, three, two);
		move(one, three);
		hanoi(n - 1, two, one, three);
	}
}


결과:

 

추천

출처blog.csdn.net/baidu_36669549/article/details/104145360