6-汉诺塔问题 (Hanoi)

汉诺塔问题(Hanoi)是一个典型的将问题分解为规模更小的子问题进行求解的案例。

1、题目描述

古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图)。有一个和尚想把这64个盘子从A座移
到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求输出移动
的步骤。
在这里插入图片描述

2、解题分析

把这n个盘子从A座移到C座的问题可以进行分解,分解为三步:1、将n-1个盘子从A挪动到B,2、将剩下的一个盘子从A挪动到C,3、将B上的n-1个盘子挪动到C。

求解过程如下:
如果n=1,则将这一个盘子直接从A柱移到C柱上。
如果n>1,则执行以下3步:

  1. 用C柱做缓冲,将A柱上的(n-1)个盘子移到B柱上。
  2. 将A柱上最后一个盘子直接移到C柱上。
  3. 用A柱做缓冲,将B柱上的(n-1)个盘子移到C柱上。
#include<iostream>
using namespace std;
//将n个盘子从src移动到dest,以mid做中转
void Hanoi(int n, char src, char mid, char dest)
{
	if (n == 1)			//只有一个盘子,直接移动就可以了
	{
		cout << src << "->" << dest << endl;
		return;			//不要忘了递归终止
	}
	Hanoi(n - 1, src, dest, mid);		//先将n-1个盘子从src移动到mid
	cout << src << "->"<<dest << endl;	//再将src上剩下的一个盘子直接移动到dest
	Hanoi(n - 1, mid, src, dest);		//最后将mid上的n-1个盘子移动到dest
}
int main()
{
	int n;		//盘子数量
	cin >> n;
	Hanoi(n, 'A', 'B', 'C');
	return 0;
}

最后为了加深理解,我们手动的移动一下只有三个盘子的汉诺塔问题。

将三个盘子从 A 移动到 C,可以分解为三个问题,先将两个盘子从 A 移动到 B,再将 A 上剩下的一个盘子移动到 C,最后将 B 上的两个盘子移动到 C。再将分解后的三个问题按照上面的步骤继续进行,直到只有一个盘子时,直接移动即可。
在这里插入图片描述

3、总结

从例子中理解递归的过程,如何将问题分解成规模更小的子问题。

猜你喜欢

转载自blog.csdn.net/happyjacob/article/details/87302407