再帰的アルゴリズム9-複雑な再帰のハノイの塔問題

 

ハノイの塔の問題は、インドの古代の伝説に由来しています。神が世界を創造されたとき、彼は3本のダイヤモンドの柱を作りました。1本の柱に、64個の金属ディスクが上から下にサイズ順に積み重ねられました。神はブラフマンに、ディスクを下からサイズ順に別の柱に戻すように命じました。また、小さなディスクではディスクを拡大できず、3つの柱の間で移動できるディスクは1つだけであると規定されています。

【分析】
この問題は、実際にはn枚のディスクをピラーAからピラーCに移動することです。ピラーBは移動中に使用できます。一度に移動できるディスクは1つだけで、大きなディスクは常に下にあり、小さな円はディスク。

ピラーBを使用してn個のディスクをピラーAからCに移動するには、最初にn-1個のディスクをピラーAからピラーCからBに移動し、次にn番目のディスクをピラーCの上部に直接移動します。次に、ピラーAを使用してn-1ディスクをピラーBからCに移動し、nの問題をn-1の問題に分解します。

このようにして、n枚のプレートを柱Aから柱Cに移動することは可能ですが、n-1枚のディスクをAからBに移動し、次に柱Bから柱Bに移動する方法という未解決の問題がまだあります。柱C。

n-1ディスクをピラーAからピラーBに移動するには、上のn-2ディスクを吸収して、Bを使用してピラーAからピラーCに移動し、次にn-1ディスクを直接Bに移動する必要があります。 Aはn-2枚のディスクをCからBに移動します。

n-1枚のディスクを列Bから列Cに移動するには、再帰が必要です。ディスクを移動するプロセスは、再帰の特性と一致しています。大きな問題は小さな問題に縮小されます。再帰の終了の条件は、一度に1つのプレートのみを移動することです。それ以外の場合、再帰は続行されます。

問題を単純化するために、Bを使用して3つのディスクを列Aから列Cに移動するプロセスを分析してみましょう。

(1)列Aの2つのディスクを列Bに移動します(列Cを使用)。
(2)列Aのディスクを列Cに直接移動します(A-> C)。
(3)列Bの2枚のディスクを列Cに移動します(列Aを使用)。

その中で、ステップ(2)は直接実行でき、ステップ(1)は分解し続けることができます。

a。列Aのディスクを列Cに直接移動します(A-> C)。
b。列Aのディスクを列Bに直接移動します(A-> B)。
c。列Cのディスクを列Bに直接移動します(C-> B)。

ステップ(3)は分解を続けることができます:

a。列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