C语言递归解决汉诺塔问题(代码含详细注解)

汉诺塔问题的来源(引用百度):

  相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

C语言递归解决汉诺塔问题(代码含详细注解)_第1张图片

分析过程(以三层为例,图片非本人所画,引用自网络,如侵权请联系删除):

这是初始状态(图1):

C语言递归解决汉诺塔问题(代码含详细注解)_第2张图片

                                                   图1

我们需要将A杆上的圆盘以大的在下,小的在上的原则放在C杆上

所以需要将A杆上前两个盘子先移走,但是因需要将最大的盘子放置到C杆底部,所以前两个盘子不能直接放到C上,而需要先放到B上(以B杆作为中转杆)

但要将前两个盘子按大的在下,小的在上的原则放到B杆上,则需要将最小的盘子先放置到C杆上(图2),再将中等的盘子放到B杆上(图3),最后将最小的盘子从C杆放到B杆上(图4),如图所示:

C语言递归解决汉诺塔问题(代码含详细注解)_第3张图片

                                                    图2

C语言递归解决汉诺塔问题(代码含详细注解)_第4张图片

                                                    图3

C语言递归解决汉诺塔问题(代码含详细注解)_第5张图片

                                                    图4

完成上述步骤后,我们可以将最大的盘子放置在C杆上(图5)

C语言递归解决汉诺塔问题(代码含详细注解)_第6张图片

                                                   图5

接下来我们需要将中等的盘子放到C杆上,则需要先将最小的盘子放在A杆上(图6),再将中等的盘子放到C杆上(图7),最后将最小的盘子放到C上(图8),如图所示:

C语言递归解决汉诺塔问题(代码含详细注解)_第7张图片

                                                    图6

C语言递归解决汉诺塔问题(代码含详细注解)_第8张图片

                                                    图7

C语言递归解决汉诺塔问题(代码含详细注解)_第9张图片

                                                    图8

此时,我们成功的解决了以三层为例的汉诺塔问题。

通过上述例子,我们得出规律:

(1)若我们需要移动的盘子上没有其他的盘子(图9),则可以直接将其移动到目标杆上(图10),如图所示:

C语言递归解决汉诺塔问题(代码含详细注解)_第10张图片

                                                    图9

C语言递归解决汉诺塔问题(代码含详细注解)_第11张图片

                                                    图10

(2)若我们需要移动的盘子上有其他的盘子(图11),则需要将其上方的盘子先移动到一根中转杆上(图12),然后才能将目标盘子移动到目标杆上(图13),如图所示:

C语言递归解决汉诺塔问题(代码含详细注解)_第12张图片

                                                     图11

C语言递归解决汉诺塔问题(代码含详细注解)_第13张图片

                                                     图12

C语言递归解决汉诺塔问题(代码含详细注解)_第14张图片

                                                     图13

所以我们在移动盘子的过程中,存在着起始杆、中转杆(存放需要移动的盘子上方的那些盘子)和目标杆(图14)

C语言递归解决汉诺塔问题(代码含详细注解)_第15张图片

                                                     图14

例如图14中,要将中等的盘子移动到目标杆C上

则起始杆为A杆,目标杆为C杆,而B作为中转杆临时存放着最小的盘子(如图13)

在C语言中利用递归思想解决此类汉诺塔问题:

以下为代码实现(含有详细注解):

void print(char x, char y) {                              //用于打印盘子的移动过程
	printf("%c->%c\n", x, y);                               //显示盘子移动过程:如A->B
}
void move(int n, char start, char temp, char end) {       //n为需要移动的盘子数量,
	                                                      //start、temp、end分别对应起始杆、中转杆、目标杆
	if (n == 1) {
		print(start, end);                                //若需要移动的盘子上没有别的盘子,则直接移动
	}
	else {
		move(n - 1, start, end, temp);                    //若需要移动的盘子上有别的盘子,则先将其上面的n-1个盘子移走,
		                                                  //上面n-1个盘子需要先停留在temp杆上,所以以end杆为中转杆,
		                                                  //temp杆为目标杆,进行转移
		print(start, end);                                //此时start杆上只有一个盘子,可以直接移动到end杆上
		move(n - 1, temp, start, end);                    //最后将之前停留在temp杆上的n-1个盘子移动到end杆上,则以temp杆
		                                                  //为起始杆,start杆为中转杆,end杆为目标杆
	}

}
int main() {
	printf("请输入汉诺塔的层数:");
	int x;
	scanf("%d", &x);
	move(x,'A', 'B', 'C');                                //传入起始杆A,中转杆B,目标杆C
	return 0;
}

代码运行结果:

C语言递归解决汉诺塔问题(代码含详细注解)_第16张图片

C语言递归解决汉诺塔问题(代码含详细注解)_第17张图片

以上为C语言利用递归思想解决汉诺塔问题的具体内容,希望本文章对您有所帮助!

如有错误需要修改,请在评论区联系我,谢谢。

你可能感兴趣的:(C语言相关技术贴,c语言,开发语言,学习,算法,数据结构)