汉罗塔问题

来源:互联网 发布:网络安全员资格证书 编辑:程序博客网 时间:2024/05/16 15:36

1.汉诺塔问题描述:

3根柱子A,B,C,A柱上有n个盘子,盘子的大小不等,大的盘子在下,小的盘子在上。

要求将A柱上的n个盘子移到C柱上,每次只能移动一个盘子。

在移动过程中,可以借助于任何一根柱子(ABC),但必须保证3根柱子上的盘子都是大的盘子在下,小的盘子在上。

2.源程序:

注:源程序中的x,y,z分别代表题目要求中的A,B,C,下面是递归和非递归算法

#include<stdio.h>

#define MAXSTACK 10   /* 栈的最大深度 */

int c = 1; /* 一个全局变量,表示目前移动的步数 */

struct hanoi { /* 存储汉诺塔的结构,包括盘的数目和三个盘的名称 */

       int n;

       char x, y, z;

};

void move(char x, int n, char y) /* 移动函数,表示把某个盘从某根针移动到另一根针 */

{

       printf("%d. Move disk %d from %c to %c\n", c++, n, x, y);

}

///*x柱上的n个盘子借助于y柱移到z柱上*/

void hanoi(int n, char x, char y, char z) /* 汉诺塔的递归算法 */

{

       if (1 == n)

              move(x, 1, z);

       else {

              hanoi(n - 1, x, z, y);// /*x柱上的n-1个盘子借助于z柱移到y柱上*/

              move(x, n, z);//把第n个盘子从x柱移动到z柱上

              hanoi(n - 1, y, x, z);//递归,把y柱上的n-1个盘子借助于x柱移到z柱上

       }

}

void push(struct hanoi *p, int top, char x, char y, char z,int n)

{

       p[top+1].n = n - 1;

       p[top+1].x = x;

       p[top+1].y = y;

       p[top+1].z = z;

}

void unreverse_hanoi(struct hanoi *p) /* 汉诺塔的非递归算法 */

{

       int top = 0;

      

       while (top >= 0) {

              while (p[top].n > 1) { /* 向左走到尽头 */

                     push(p, top, p[top].x, p[top].z, p[top].y, p[top].n);

                     top++;

              }

              if (p[top].n == 1) { /* 叶子结点 */

                     move(p[top].x, 1, p[top].z);

                     top--;

              }

              if (top >= 0) { /* 向右走一步 */

                     move(p[top].x, p[top].n, p[top].z);

                     top--;

                     push(p, top, p[top+1].y, p[top+1].x, p[top+1].z, p[top+1].n);

                     top++;

              }

       }

}

int main(void)

{

       int i;

       struct hanoi p[MAXSTACK];

       printf("reverse program:\n");

       hanoi(3, 'x', 'y', 'z');

       printf("unreverse program:\n");

       c = 1;

       p[0].n = 3;

       p[0].x = 'x', p[0].y = 'y', p[0].z = 'z';

       unreverse_hanoi(p);

      

       return 0;

}

程序的运行结果如下所示:

reverse program:

1. Move disk 1 from x to z

2. Move disk 2 from x to y

3. Move disk 1 from z to y

4. Move disk 3 from x to z

5. Move disk 1 from y to x

6. Move disk 2 from y to z

7. Move disk 1 from x to z

unreverse program:

1. Move disk 1 from x to z

2. Move disk 2 from x to y

3. Move disk 1 from z to y

4. Move disk 3 from x to z

5. Move disk 1 from y to x

6. Move disk 2 from y to z

7. Move disk 1 from x to z

Press any key to continue

3.起源:

汉诺塔是源自印度神话里的玩具。

如果移动一个圆盘需要1秒钟的话,等到64个圆盘全部重新落在一起,宇宙被毁灭是什么时候呢?

汉诺塔与宇宙寿命

让我们来考虑一下64个圆盘重新摞好需要移动多少次吧。1个的时候当然是1次,2个的时候是3次,3个的时候就用了7......这实在是太累了

  因此让我们逻辑性的思考一下吧。

  4个的时候是

  “3个圆盘重新摞在一起的次数”+1+3个圆盘重新摞在一起需要的次数”

  =2x3个圆盘重新摞在一起的次数”+1

  =15次。

  那么,n个的时候是

  2x“(n-1)个圆盘重新摞在一起的次数”+1次。

  由于个的时候是1次,结果n个的时候为(2n次方减1)次。

  1个圆盘的时候 21次方减1

  2个圆盘的时候 22次方减1

  3个圆盘的时候 23次方减1

  4个圆盘的时候 24次方减1

  5个圆盘的时候 25次方减1

  ........

  n个圆盘的时候 2n次方减1

  也就是说,n=64的时候是(264次方减1)次。

  因此,如果移动一个圆盘需要1秒的话,

  宇宙的寿命=264次方减1(秒)

  264次方减1到底有多大呢?动动计算器,答案是一个二十位的数字:

  18446744073709551615

  用一年=60x60x24小时x365天来算的话,大约有5800亿年吧。

  据说,现在的宇宙年龄大约是150亿年,还差得远呢。

  汉诺塔问题在数学界有很高的研究价值,

  而且至今还在被一些数学家们所研究,
0 0
原创粉丝点击