您的位置:首页 > 理论基础 > 数据结构算法

16、数据结构笔记之十六栈的应用之栈与递归之汉诺塔问题

2017-09-14 00:00 288 查看
16、蛤蟆的数据结构笔记之十六栈的应用之栈与递归之汉诺塔问题
       “人生的价值,并不是用时间,而是用深度去衡量的。

       继续栈与递归应用,汉诺塔问题。

 

1.  汉诺塔问题

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。这需要多少次移动呢?这里需要递归的方法。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不难证明f(n)=2^n-1。n=64时,

假如每秒钟一次,共需多长时间呢?一个平年365天有31536000 秒,闰年366天有31622400秒,平均每年31556952秒,计算一下:

18446744073709551615秒

这表明移完这些金片需要5845.54亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。真的过了5845.54亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。

 

 

2.  源码

调试时候不要输入太大的数字,小心灰飞烟灭~

#include"stdio.h"
void hanoi(intn,chara,charb,charc)
{
           if(n==1)
                     printf(" 
将%d个盘直接从%c移到%c\n",n,a,c);
           else
           {
                     hanoi(n-1,a,c,b);
                                printf(" 
将第%d个盘从%c移动到%c\n",n,a,c);
                     hanoi(n-1,b,a,c);
           }
}
void main()
{
           int n;
           printf("请输入需要移动的盘子的个数\n");
           scanf("%d",&n);
           printf("***********************************\n");
           hanoi(n,'x','y','z');
           printf("***********************************\n");
}
如下图1所示:

3.  递归缺点

递归有一个重要的缺点。使用递归函数时,在还没有结束递归过程时,每个计算过程所产生的数据以及变量的值和返回地址都将存储起来,也称作“保护现场”,如果当这个函数所进行的次数非常多的时候,系统就会产生非常多的临时数据,而系统都会把这些数据存放起来,造成了非常占用内存,数据达到一定的数据量时,可能导致电脑会死机。所以,递归函数好用,我们也要小心的用。

在递归过程中,其实我们并不用去了解计算机内部的操作,因为这些计算机系统本身就会自己建立一个栈来存放数据,等到递归结束后系统会自动的开始读取数据和返回值。等到递归全部结束后,系统就会释放存放临时数据的栈的空间。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: