汉诺塔递归算法C语言

2020-09-1310:42:28

@

19世纪的时候,法国数学家爱德华·卢卡斯创造了一个叫汉诺塔的神话:佛教大神梵天在创造世界的时候有点无聊,顺便造了三根金刚石柱子,其中第一根柱子上堆了64块黄金圆盘。梵天命令僧侣把所有圆盘从第一根柱子移动到第三根柱子上,且每次只能移动一片,小圆盘必须在大圆盘的上面。

梵天对僧侣说,如果全部把圆盘搬完,世界将会毁灭,所有的佛塔、庙宇、僧侣都将在烈火中化为灰烬。

 

僧侣搬完所有圆盘,需要多长时间?这个问题可以用递归算法来求解。

 

递归

递归算法在程序设计中被广泛应用。根据度娘的解释,递归,就是函数直接或间接地调用函数自身,直到引用对象可知。(有点像现在流行的“套娃”梗)

递归有一个好处,就是可以把复杂的步骤简化成几个简单的步骤,从而实现对复杂问题的一步步拆解。

比如,在汉诺塔游戏中,要把n个圆盘按上述规则从A柱子移动到C柱子上,我们可以按三个大步骤去做:

1、先把上面的n-1个圆盘移动到B柱子;

 

2、把第n个(即最底层的那个)圆盘移动到C柱子;

 

3、最后把n-1个圆盘从B柱子移动到C柱子,就完成了。

 

而回到第一个步骤,怎么把n-1个圆盘按规则移动到B柱子上呢?可以继续进行拆解,先把n-2个圆盘移动到C柱子上,然后把第n-1个圆盘移动到B柱子上,最后把n-2个圆盘从C柱子移动到B柱子……

这样一直拆解下去,最终就可以分解为每次只移动一个圆盘的步骤了。

拆解的流程如下:

于是,就有这样的结论:

回到最初的问题,如果僧侣需要把64个圆盘从第一根柱子移动到第三根柱子,需要搬动(2^64-1)次,假设每秒钟搬动一次,共需要5800亿年。

 1 /*汉诺塔递归算法*/ 
 2 #include <stdio.h>
 3 void move(int n,char x,char y)
 4 {
 5     printf("%c-->%c\n",x,y);
 6 }
 7 void hanota(int n,char A,char B,char C)
 8 //一共n个盘子,要把这n个盘子借助B柱子从A柱子全部移到C柱子 
 9 {
10     if(n==1)//递归出口,也就是结束的标志 
11     {
12         move(n,A,C);//当只有一个盘子的时候,直接从A柱子移到C柱子 
13     }
14     else 
15     {
16         hanota(n-1,A,C,B);//当n>1时,把(n-1)个盘子借助C柱子从A柱子移到B柱子 
17         move(n,A,C);//然后把第n个盘子从A柱子移到C柱子 
18         hanota(n-1,B,A,C);//再把(n-1)个盘子借助A柱子从B柱子移到C柱子 
19     }
20 }
21 //主函数 
22 int main() 
23 {
24     int m;
25     char a='A',b='B',c='C';
26     scanf("%d",&m);//输入有几个盘子 
27     hanota(m,a,b,c);
28     return 0;
29 }

 

posted @ 2020-09-13 10:46  zhou小月  阅读(3277)  评论(1编辑  收藏  举报