汉诺塔C递归算法详细解答
python汉诺塔递归详解(一)
python汉诺塔递归详解(一)Python汉诺塔递归解法引言汉诺塔(Hanoi Tower)是一种数学问题和益智游戏,由法国数学家爱德华·卢卡教授在19世纪初提出。
通过计算机编程解决汉诺塔问题,可以帮助我们更好地理解递归算法在编程中的应用。
问题描述在汉诺塔问题中,有三个柱子和一些圆盘,每个柱子上的圆盘按照从小到大的顺序叠放。
问题的目标是将所有圆盘从一根柱子移动到另一根柱子上,每次只能移动一个圆盘,并且在移动过程中不允许大圆盘放在小圆盘上面。
解法思路我们可以使用递归的方法解决汉诺塔问题。
下面是解决汉诺塔问题的基本步骤:1.将上面n-1个圆盘从A柱移动到B柱。
2.将最大的圆盘从A柱移动到C柱。
3.将B柱上的n-1个圆盘移动到C柱。
通过递归调用这三个步骤,可以将所有的圆盘从A柱移动到C柱。
代码实现以下是使用Python语言实现汉诺塔递归的代码:def hanoi(n, A, B, C):if n == 1:print("Move disk 1 from", A, "to", C) returnhanoi(n-1, A, C, B)print("Move disk", n, "from", A, "to", C) hanoi(n-1, B, A, C)# 测试代码hanoi(3, "A", "B", "C")运行结果运行上述代码,我们可以得到以下输出结果:Move disk 1 from A to CMove disk 2 from A to BMove disk 1 from C to BMove disk 3 from A to CMove disk 1 from B to AMove disk 2 from B to CMove disk 1 from A to C总结通过递归算法,我们可以轻松解决汉诺塔问题。
汉诺塔解题思路
汉诺塔解题思路汉诺塔解题思路汉诺塔塔问题符合数学统计归纳,千万别试图去理解n层移动问题(或者说去理解n层递归,⼈脑真不够⽤),理解3层汉诺塔问题就⾏。
总结起来如下:递归的理解的要点主要在于放弃!放弃你对于理解和跟踪递归全程的企图,只理解递归两层之间的交接,以及递归终结的条件。
解题算法1. 如果A柱⼦只剩⼀个盘⼦,那么直接移动到C柱⼦即可2. 把 n-1 号盘⼦移动到缓冲区3. 把1号从起点移到终点4. 然后把缓冲区的n-1号盘⼦也移到终点解题框架/*1.要从a到b 那c就是缓冲 move(n-1,from,to,buffer)2.要从a到c 那b就是缓冲 move(1,from,buffer,to)3.要从b到c 那a就是缓冲 move(n-1,buffer,from,to)*///汉诺塔移动框架void move(n,from,buffer,to){if (n == 1) {removeTo(from,to);return;}move(n-1,from,to,buffer);move(1,from,buffer,to);move(n-1,buffer,from,to);}void removeTo(List<Integer> from, List<Integer> to) {to.add(from.remove(from.size() - 1));}Java代码//汉诺塔问题解释https:///question/24385418public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {remove(A.size(),A,B,C);}private void remove(int n, List<Integer> from, List<Integer> buffer, List<Integer> to) {//如果A柱⼦只剩⼀个盘⼦,那么直接移动到C柱⼦即可if (n == 1) {removeTo(from,to);return;}//1.把 n-1 号盘⼦移动到缓冲区//把A柱⼦上⾯的n-1个盘⼦,借助辅助柱⼦C,放到柱⼦B上remove(n - 1, from, to, buffer);//2.把1号从起点移到终点//此时A柱⼦剩下那个盘⼦是n个盘⼦中最⼤的那个,把他移动到C柱⼦上remove(1, from,buffer,to);//3.然后把缓冲区的n-1号盘⼦也移到终点//最后把刚才放在B柱⼦上的n-1个盘⼦,借助柱⼦A辅助,放到柱⼦C上remove(n - 1, buffer, from, to);}private void removeTo(List<Integer> from, List<Integer> to) {to.add(from.remove(from.size() - 1));}。
四柱汉诺塔问题数学公式
四柱汉诺塔问题的数学推导简介汉诺塔问题是一种经典的数学难题,涉及到递归和数学推理。
该问题描述如下:有三根柱子,分别记为A、B、C,初始状态下,在A柱子上有一个由小到大依次排列的套圈。
现在的目标是将所有套圈按照相同的顺序搬到C柱子上,期间可以借助B柱子作为中间过渡。
同时,在四柱汉诺塔问题中,我们引入了第四根柱子D,当进行移动的圈数大于3时,可以在D柱子上进行临时存储。
问题分析首先,我们需要分析一下问题的关键要素: 1. 圈的数量:假设我们有n个圈需要移动 2. 柱子的数量:假设我们有m根柱子,其中m>3推导过程1. n=1时,m=3时的情况当n=1时,表示只有一个圈需要移动。
这时,根据汉诺塔问题的规则,我们可以直接将该圈从A柱子移动到C柱子上即可。
2. n=2时,m=3时的情况当n=2时,表示有两个圈需要移动。
这时,我们可以采用递归的思想,将问题分解为多个子问题。
具体步骤如下: - 步骤1:先将n-1个圈从A柱子移动到临时柱子B上; - 步骤2:将第n个圈从A柱子移动到目标柱子C上; - 步骤3:将n-1个圈从临时柱子B移动到目标柱子C上。
3. n>2时,m=3,4时的情况当n>2时,我们同样可以采用递归的思想,将问题分解为多个子问题。
不同的是,在四柱汉诺塔问题中,我们可以借助第四根柱子D来完成移动。
具体步骤如下: - 步骤1:先将n-m个圈从A柱子移动到临时柱子B上; - 步骤2:将前m个圈从A柱子移动到目标柱子D上; - 步骤3:将n-m个圈从临时柱子B移动到目标柱子C上; - 步骤4:将前m个圈从目标柱子D移动到目标柱子C上; - 步骤5:将n-m个圈从A柱子移动到目标柱子D上; - 步骤6:将前m个圈从目标柱子C移动到目标柱子D上; - 步骤7:将n-m个圈从A柱子移动到目标柱子C 上。
根据上述步骤,我们可以总结出递归的数学公式如下:H(n,m) = 2H(n-m,m)+2^m-1其中,H(n,m)表示有n个圈需要移动的情况下,借助m根柱子完成的最小次数。
采用递归和非递归方法求解hannol问题
采用递归和非递归方法求解hannol问题汉诺塔问题是数学中的经典问题之一,也被认为是计算机科学中的经典问题。
它的解法可以使用递归或非递归的方法。
在本文中,我们将介绍并比较这两种解法。
汉诺塔问题的描述是:有三根柱子,A、B、C,初始时,A柱子上有n个盘子,这些盘子从小到大按顺序堆叠在一起。
现在需要将这n 个盘子从A柱子移动到C柱子上,期间可以借助B柱子。
移动盘子有以下几个规则:1.每次只能移动一个盘子;2.盘子只能从大盘子移到小盘子上;3.在移动过程中,可以借助柱子进行中转。
接下来,我们将先介绍递归解法。
递归解法:对于n个盘子,我们可以将问题分解为以下三个步骤:1.将n-1个盘子从A柱子移动到B柱子;2.将第n个盘子从A柱子移动到C柱子;3.将n-1个盘子从B柱子移动到C柱子。
递归解法的代码如下:```pythondef hanoi(n, A, B, C):if n == 1:print("Move disk %d from %s to %s" % (n, A, C)) else:hanoi(n-1, A, C, B)print("Move disk %d from %s to %s" % (n, A, C)) hanoi(n-1, B, A, C)```在这个递归函数中,n表示盘子的数量,A、B、C表示三根柱子。
当n为1时,直接将第一个盘子从A柱子移动到C柱子;否则,先将n-1个盘子从A柱子移动到B柱子,然后将第n个盘子从A柱子移动到C柱子,最后将n-1个盘子从B柱子移动到C柱子。
递归的过程中,会不断地将问题分解为子问题,直到子问题规模减小到1。
下面是一个具体的例子,假设有3个盘子,初始时都在A柱子上:```pythonhanoi(3, 'A', 'B', 'C')```输出结果为:```Move disk 1 from A to CMove disk 2 from A to BMove disk 1 from C to BMove disk 3 from A to CMove disk 1 from B to AMove disk 2 from B to CMove disk 1 from A to C```如上所示,递归解法将问题分解为子问题,然后逐步解决子问题,最后得到整体的解。
用C语言解决汉诺塔问题的方法及过程分析
( )将 原 问题 转化 成 新 问题 后 ,能使 求 解算法 的规模减 小. 2
( )递归 有一 个 明显 的 出 口,或称 为递 归的边 界 ,而边 界 问题 的解是显 而 易见 的或 已知 的. 3
3 用 C语 言 编 程
C语 言是 一种 在 国内外 广泛 流行 的高 级程 序设 计语 言 ,它 的语 言 功能 丰富 ,表达 力 强 ,使 用 灵 活 ,应
言 中 ,用 递归 法编 写 条件
2 1 递 归程序 定义 .
《 C程 序设 计 》 数 据结 构 》等教科 书 中 ,都对 递 归 程 序 给 出 了基本 相 同的定 义 ,归纳 如下 :在调 用 、《
一
个 函数 的过 程 中 ,又直接 或 间接地 调用 了该 函数本 身 ,称 为 函数 的递 归调 用 ,使用 了递 归调用 函数 的程
第 3期
{ a ( 一 , o e t r e t ) hn n1 n , h e , wo ;
mo e ( ne, t e ); v o hr e
h n ( 一 ,t a n 1 wo,o e h e ) ) n ,t r e ;)
ma n ( i )
{n i tn;
prn f ( “ e s nt rt mbe ike ” it Pla e e e he nu rofd s s: );
维普资讯
维普资讯
2 0 年 6月 06
河 北 北 方 学 院学 报 ( 自然 科 学 版 )
第 3 期
上操 作 的实质 是把移 动 n个 盘子 的 问题转 化 为移 动 n 一1个盘 .那 一 、三 步 如何解 决 ?事 实 上 ,上述 方法 设盘 子数 为 n ,n可 为任 意数 ,该 法 同样 适 用于 移动 n 1 盘. 因此 ,依 据 上 法 ,可解 决 n 一 个 一1个 盘子从 A杆 移 到 B杆 ( 一 步)或 从 B杆 移到 C杆 ( 第 第三 步 ) 问题 .现 在 ,问题 由移 动 n个 盘 子 的操 作转 化 为 移动 n 一2个 盘子 的操作 .依 据该 原 理 ,层 层递 推 ,即可将 原 问题 转化 为 解 决移 动 n 、n … …3 、 一2 一3 、2 直 到移动 1 盘 的操 作 ,而移 动一 个 盘 的操 作 是可 以 直接 完成 的. 至 此 ,我 们 的任 务 算作 是 真 正完 成 了. 个 而这 种 由繁化 简 ,用简单 的问题 和 已知 的操 作 运算来 解决 复杂 问题 的方 法 ,就是 递归法 . 在计算 机设计 语
python汉诺塔递归算法
python汉诺塔递归算法汉诺塔递归算法是一种经典的递归算法,用于解决汉诺塔问题。
汉诺塔问题是一个古老的数学问题,它由法国数学家爱德华·卢卡斯于1883年提出。
问题的描述如下:有三根柱子A、B、C,A柱子上有n个盘子,盘子大小不一,大的在下,小的在上。
现在要将A柱子上的盘子全部移到C柱子上,但是移动过程中有以下限制条件:1.每次只能移动一个盘子;2.大盘子不能放在小盘子上面。
汉诺塔递归算法的思路是将问题分解成若干个子问题,然后递归地解决这些子问题。
具体来说,我们可以将问题分解成三个步骤:1.将A柱子上的n-1个盘子移动到B柱子上;2.将A柱子上的最后一个盘子移动到C柱子上;3.将B柱子上的n-1个盘子移动到C柱子上。
这样,我们就将原问题分解成了三个子问题,而这三个子问题的解决方法与原问题是相同的,因此我们可以使用递归算法来解决这个问题。
下面是汉诺塔递归算法的Python代码实现:def hanoi(n, A, B, C):if n == 1:print(A, "->", C)else:hanoi(n-1, A, C, B)print(A, "->", C)hanoi(n-1, B, A, C)在这个代码中,n表示盘子的数量,A、B、C分别表示三根柱子。
当n等于1时,我们直接将A柱子上的盘子移动到C柱子上;当n 大于1时,我们先将A柱子上的n-1个盘子移动到B柱子上,然后将A柱子上的最后一个盘子移动到C柱子上,最后将B柱子上的n-1个盘子移动到C柱子上。
汉诺塔递归算法的时间复杂度为O(2^n),因为每个盘子都需要移动2^n-1次。
虽然时间复杂度很高,但是汉诺塔递归算法是一种非常优美的算法,它展示了递归算法的精髓,也是计算机科学中的经典问题之一。
汉诺塔的时间复杂度递推公式
汉诺塔的时间复杂度递推公式
汉诺塔问题是一个数学谜题,也是计算机科学中经典的问题之一。
汉诺塔问题需要将一堆盘子从一个柱子移动到另一个柱子,规则是每次只能移动一个盘子,并且大盘子不能放在小盘子上面。
汉诺塔问题在算法分析中具有重要性,因为它能够展示递归算法的应用。
在汉诺塔问题中,我们可以通过递归算法来解决。
假设我们有n 个盘子,它们被放置在柱子A上。
我们需要将它们全部移动到柱子C 上。
我们定义递归函数hanoi(n,A,B,C)表示将n个盘子从柱子A移
动到柱子C,其中B表示辅助柱子。
递归函数hanoi(n,A,B,C)的时间复杂度可以使用递推公式来表示:
T(n) = 2T(n-1) + 1
其中T(n-1)表示n-1个盘子从A移动到B所需的时间,2T(n-1)表示将n-1个盘子从A移动到B,再将最大的盘子从A移动到C,最
后将n-1个盘子从B移动到C所需的时间,1表示将最大的盘子从A
移动到C所需的时间。
由此递推得到时间复杂度:
T(n) = 2^n - 1
因此,汉诺塔问题的时间复杂度为指数级别,随着盘子数量的增加,时间复杂度增长非常快。
- 1 -。
c语言递归汉诺塔每一步详解
递归汉诺塔是一个经典的递归问题,它要求将一堆圆盘从一根柱子移动到另一根柱子上,且规定不能通过其他圆盘。
这个问题可以通过递归算法来解决。
在每一步中,我们可以选择将当前最大的圆盘从起始柱子移动到目标柱子,或者将两个较小的圆盘移动到另一个柱子上。
递归函数需要考虑三个柱子的状态:起始柱子、目标柱子和柱子。
在函数中,我们需要判断当前情况是否可以进行移动,如果可以,则执行相应的移动操作,否则返回上一个递归函数继续执行。
最终,当所有圆盘都移到目标柱子上时,问题得到解决。
汉诺塔游戏:递归经典问题
汉诺塔游戏:递归经典问题汉诺塔游戏,是非常著名的智力趣味题,在很多算法书籍和智力竞赛中都有涉及。
汉诺塔游戏的基本规则是:在一块板子上,有三根编号分别为A、B、C的杆,在A杆上按自下而上、由大到小的顺序放置着64个(或其他数目)圆盘,每次只能移动一个圆盘,并且在移动过程中三根杆上都始终保持大盘在下、小盘在上的状态,操作过程中圆盘可以在A、B、C任意一杆上,要如何把A杆上的圆盘全部移到C杆上?以3个圆盘为例:将3个圆盘按由小到大的顺序分别记作P1、P2、P3。
按照规则将三个圆盘从A杆移至C杆,则需以下步骤:(1)先将P1移至C杆,再将P2移至B杆,然后将P1移至B杆,此时P1和P2均在B杆上(需3步);(2)将P3移至C杆(需1步);(3)将P1移至A杆,将P2移至C杆,最后将P1移至C杆(需3步)。
在此过程中,要将P3移至C杆,先将C杆当作中介,将P1移至C杆;再将P1、P2先移至B杆,借用B杆做中介;再将P2移至C杆时,又先将P1移至A杆,借用了A杆做中介。
(总共7步完成)以此为例,如何完成其他数量圆盘的移动操作呢?当n=1时,只需将编号为1的圆盘从A柱直接移至C柱上即可。
当n=2时,利用B柱作为辅助柱,先将圆盘1移至B柱,再将圆盘2由A柱直接移至C柱,然后再将圆盘1由B柱移至C柱。
当n=3时,同样利用B柱作为辅助柱,依照上述原则,先设法将圆盘1、2移至B柱,待圆盘3由A柱移至C柱后,再依照上述原则设法将圆盘1、2移至C柱。
......依此类推,当n>1时,需利用B柱作为辅助柱,先设法将压在编号为n的圆盘上的n-1个圆盘从A柱(依照上述原则)移至C柱,待编号为n的圆盘从A柱移至C柱后,再将B柱上的n-1个圆盘(依照上述原则)移至C柱。
游戏的移动操作很简单,但是如何将64个圆盘从一根杆子上移到另一根杆子上,并且始终保持上小下大的顺序,一共需要移动多少次才是让人头疼的问题。
游戏过程中不难发现:不管把哪一个圆盘移到另一根杆子上,移动的次数都要比移动上面一个增加一倍。
c语言汉诺塔问题递归算法
c语言汉诺塔问题递归算法汉诺塔问题是经典的递归问题,要求将n个大小不同的盘子从起始柱移动到目标柱,并遵循以下规则:1.大盘子不能在小盘子上方移动。
2.每次只能移动一个盘子。
在C语言中,我们可以使用递归算法来解决汉诺塔问题。
以下是一个简单的示例代码:```c#include<stdio.h>voidhanoi(intn,charfrom,charto,charaux){if(n==1){//只有一个盘子时,直接移动到目标柱printf("Movedisk1from%cto%c\n",from,to);}else{//递归地将n-1个盘子从起始柱移动到辅助柱,再将最后一个盘子从起始柱移动到目标柱hanoi(n-1,from,aux,to);printf("Movedisk%dfrom%cto%c\n",n,from,to);hanoi(n-1,aux,to,from);}}intmain(){intn;printf("Enterthenumberofdisks:");scanf("%d",&n);hanoi(n,'A','C','B');//从起始柱A开始,目标柱C,辅助柱Breturn0;}```在上述代码中,我们定义了一个名为hanoi的函数,用于实现汉诺塔问题的递归解法。
该函数接受四个参数:n表示盘子的数量,from表示起始柱,to表示目标柱,aux表示辅助柱。
当只有一个盘子时,直接移动到目标柱;否则,我们通过递归调用将n-1个盘子从起始柱移动到辅助柱,再将最后一个盘子从起始柱移动到目标柱。
在主函数中,我们从用户输入获取盘子的数量,并调用hanoi函数开始解决问题。
通过使用递归算法,我们可以将复杂的问题分解为更小的子问题,从而方便地解决问题。
在汉诺塔问题中,我们将n个盘子从起始柱移动到目标柱的问题分解为将n-1个盘子从起始柱移动到辅助柱和将最后一个盘子从起始柱移动到目标柱两个子问题。
汉诺塔递推公式
汉诺塔递推公式
汉诺塔问题是经典的递归问题,但是递归算法复杂度较高,需要进行优化。
通过分析汉诺塔问题可以发现,移动盘子数为n时,需要移动的次数为2^n-1,同时移动过程中,每个盘子只会被移动一次。
因此,我们可以通过递推公式来计算汉诺塔问题的解法。
设H(n)表示移动n个盘子所需移动的次数,H(1)=1,H(n)=2*H(n-1)+1。
递推公式的意义是:将n个盘子从A柱借助B柱移动到C柱的最小步数等于将n-1个盘子从A柱借助C柱移动到B柱的最小步数乘以2加1。
使用递推公式可以大大减少汉诺塔问题的时间复杂度,从而提高算法的效率。
- 1 -。
C语言递归调用实例——汉诺塔问题动画实现(附完整代码)
二、程序框架
古人云,不谋全局者,不足谋一域。同样,在编写代码之前,我们必 须得有个大体的思路和整体上的把握。不能一上来就稀里糊涂地乱敲一通。 当然,这里我也只能仅仅谈自己的个人想法,不一定就是最优的解决方案, 还希望能和大家一起相互交流,共同进步。整个程序的框架,我把它分为 动画效果和核心算法两大部分。我首先实现的是动画效果部分,等能够实 现盘子的随意移动后,我才开始研究核心算法的实现。这样一来,在核心 算法部分,我们正好可以利用前面的动画效果来直观地反映出我们的思路, 有助于代码的调试和缩短程序的开发周期。为了尽量减少废话,我们可以 用一张图来进行表示:
图 1-1 移动第一个圆盘..................................................................................................................... 4 图 1-2 移动第二个圆盘...................................................................................................................... 5 图 1-3 移动最后一个圆盘................................................................................................................. 6
能移动一个圆盘,且圆盘在放到棒上时,大的不能放在小的上面。中间的一根
棒作为辅助移动用。” 事实上,对此曾经有人作过分析,按这个规则,众僧耗尽毕生精力也
不可能完成圆盘的移动,因为需要移动圆盘的次数是一个天文数字 18446744073709551615(64 个圆盘需要移动的次数为 2 的 64 次方)。假设 1us 进行一次移动,也需要约一百万年的时间,使用计算机也很难解决 64
汉诺(Hanoi)塔问题(C#版)
汉诺(Hanoi)塔问题(C#版)
⼀个只能⽤递归解决的数学问题;问题描述:古代有⼀个梵塔,塔内有3个座,A、B、C,开始时A座有64个盘,盘⼦⼤⼩不等,⼤的在上,⼩的在下。
有⼀个⽼和尚想把这64个盘⼦从A座移到C座(如图所⽰),但每次只允许移动⼀个盘,且在移动过程中在3个座上始终保持⼤盘在下,⼩盘在上。
在移动地程中可以⾏⽤B座,要求编程序打印出移动的步骤。
逆向推理:1.假如⼀个和尚能把上⾯63个盘⼦先搬到B座,第⼆个和尚再把最⼤的那个移到C,第三个和尚再把63个盘⼦移到C座;⾄此整个⼯作就完成的。
2.问题是怎么才能把63个盘⼦移到B座,按照同样的⽅法,先把62个盘⼦选移到C座
,再把第63个盘⼦移到B座,最后再将62个盘⼦移到B座。
3……如此类推;
4.从上⾯分析可以看出:只有等后⾯那个和尚搬完盘⼦,前⾯的和尚才能够去完成任。
让我们来栈的数据结构:数据的处理只在⼀端处理,且是先进后出。
所以⽤递归的⽅法去处理是正确的。
(汉诺塔图)
汉诺塔问题解决⽅案
如果你发现有什么错误之处,请指出!谢谢了。
江西科学技术版小学信息技术五年级下册《跨学科主题:解密玩具汉诺塔》同步练习题附知识点归纳
江西科学技术版小学信息技术五年级下册《跨学科主题:解密玩具汉诺塔》同步练习题附知识点归纳一、课文知识点归纳:1、汉诺塔游戏介绍:(1)起源:汉诺塔游戏源于古老的印度传说。
(2)规则:有三根银针,其中一根上有大小不同的金片。
(3)目标是将所有金片从一根针移动到另一根针上,同时保持金片从大到小的顺序。
移动时,一次只能移动一个金片,且小金片不能放在大金片之上。
2、汉诺塔的基本解法:(1).递归思想:大问题可以分解为小问题来解决。
(2).步骤:首先,将n1个金片从起始针移动到辅助针;然后,将剩余的最大金片移动到目标针;最后,将n1个金片从辅助针移动到目标针。
二、同步练习题。
(一)、填空题。
1. 汉诺塔是一个源自_______的古老益智游戏,它有三根杆子和一些大小不同的圆盘。
2. 在汉诺塔游戏中,一次只能移动_______个圆盘,且大的圆盘不能放在小的圆盘之上。
3. 递归算法在解决汉诺塔问题时,将问题分解为_______个步骤,每个步骤都是一个更小规模的汉诺塔问题。
(二)、选择题。
1. 汉诺塔游戏中,如果我们想要把3个圆盘从A杆移到C 杆,首先应该怎么做?()A. 把第1个圆盘从A杆移到B杆B. 把第1个圆盘从A杆移到C杆C. 把第3个圆盘从A杆移到B杆D. 把第3个圆盘从A杆移到C杆2. 递归算法在解决汉诺塔问题时,主要依赖的是___。
()A. 顺序思维B. 逆向思维C. 分而治之的策略D. 穷举法3. 在汉诺塔游戏中,移动圆盘的过程中,以下哪个规则是不正确的?()A. 圆盘必须按顺序移动B. 一次可以移动多个圆盘C. 大圆盘不能放在小圆盘之上D. 移动圆盘时,只能从一个杆子移到另一个杆子(三)、判断题。
(正确的打“√”,错误的打“×”)1. 汉诺塔游戏的目标是将所有圆盘从一个杆子移动到另一个杆子。
()2. 递归算法在解决汉诺塔问题时,不需要考虑子问题的解。
()3. 在汉诺塔游戏中,大的圆盘总是先被移动。
递归算法详解
递归算法详解递归详解通过运⾏时堆栈来⽀持递归的调⽤,在我们刚接触递归的时候,国内很多教材都采⽤求阶乘和菲波那契数列来描述该思想,就如同深受⼤家敬爱的国产的C语⾔程序设计,⽼谭也⽤了阶乘来描述递归,以⾄于很多新⼿⼀看见阶乘就理所当然的认为是递归,坑了不少⼈,说实在的,描述这个思想还是可以,但是利⽤递归求阶乘可是没有⼀点好处,递归解决菲波那契数列效率更是低得惊⼈,这点是显⽽易见的!废话不多说,接下来我们进⼊正题!(不过说实话,我很讨厌接下来这些太理论的东西,说到底就是那么个意思,⼤家懂就好了,也可以当看看故事!我主要说的就是各种各样递归的实例)1:递归算法的思想递归算法是把问题转化为规模缩⼩了的同类问题的⼦问题。
然后函数(或过程)来表⽰问题的解。
在C语⾔中的运⾏堆栈为他的存在提供了很好的⽀持,过程⼀般是通过函数或⼦过程来实现。
递归算法:在函数或⼦过程的内部,直接或者间接地调⽤⾃⼰的算法。
2:递归算法的特点:递归算法是⼀种直接或者间接地调⽤⾃⾝算法的过程。
在计算机编写程序中,递归算法对解决⼀⼤类问题是⼗分有效的,它往往使算法的描述简洁⽽且易于理解。
递归算法解决问题的特点:(1) 递归就是在过程或函数⾥调⽤⾃⾝。
(2) 在使⽤递归策略时,必须有⼀个明确的递归结束条件,称为递归出⼝。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运⾏效率较低。
所以⼀般不提倡⽤递归算法设计程序。
(4) 在的过程当中系统为每⼀层的返回点、局部量等开辟了栈来存储。
递归次数过多容易造成等。
所以⼀般不提倡⽤递归算法设计程序。
3:递归算法的要求递归算法所体现的“重复”⼀般有三个要求:⼀是每次调⽤在规模上都有所缩⼩(通常是减半);⼆是相邻两次重复之间有紧密的联系,前⼀次要为后⼀次做准备(通常前⼀次的输出就作为后⼀次的输⼊);三是在问题的规模极⼩时必须⽤直接给出解答⽽不再进⾏,因⽽每次递归调⽤都是有条件的(以规模未达到直接解答的⼤⼩为条件),⽆条件递归调⽤将会成为死循环⽽不能正常结束。
fibonacci数列和hanoi塔问题递归算法的时间复杂度
fibonacci数列和hanoi塔问题递归算法的时间复杂度在计算机科学中,递归算法是一种常见的解决问题的方式。
本文将分析两种著名的递归算法:Fibonacci数列和Hanoi塔问题的时间复杂度。
一、Fibonacci数列的递归算法时间复杂度分析Fibonacci数列是这样一个数列:0,1,1,2,3,5,8,...。
其递归算法的基本思路是:当输入为n时,输出Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)。
然而,这种递归算法的效率并不高,其时间复杂度为O(2^n)。
因为在每一步计算中,都需要计算Fibonacci(n-1)和Fibonacci(n-2),这就导致了指数级的时间增长。
二、Hanoi塔问题的递归算法时间复杂度分析Hanoi塔问题是一个经典的递归问题。
问题描述如下:有一组大小不同的盘子,从大到小依次放在一个柱子上。
现在需要将这组盘子从柱子上移动到另一个柱子上,每次只能移动一个盘子,且小盘子不能叠在大盘子上。
Hanoi塔问题的递归算法的基本思路是:将n个盘子从柱子A移动到柱子B,可以分为以下三个步骤:1.将n-1个盘子从柱子A移动到柱子C;2.将第n个盘子从柱子A移动到柱子B;3.将n-1个盘子从柱子C移动到柱子B。
这个递归算法的时间复杂度也为O(2^n)。
三、两种递归算法的比较与总结Fibonacci数列和Hanoi塔问题的递归算法都具有指数级的时间复杂度,即O(2^n)。
这是因为这两种算法在解决问题时,都需要进行大量的重复计算。
然而,在实际应用中,这两种算法仍有其独特的优势。
1.Fibonacci数列的递归算法在研究斐波那契数列的性质和应用时非常有用,如在金融、生物学等领域。
2.Hanoi塔问题的递归算法在计算机科学中有着广泛的应用,如在操作系统中的磁盘调度、网络数据传输等领域。
尽管这两种算法的时间复杂度相同,但它们所解决的问题和应用场景有所不同。
汉诺塔游戏递归
先考虑简单情形。如果n=3,则具体移动步骤如图17-1所示:
图:17-1只有三个盘的汉诺塔游戏天字第一号示意图
如图17-2所示,假设把上面的第3步,第4步,第7步抽出来就相当于n=2的情况(但第3步要调用过程mov(n-1,a,b,c),即第1、第2步;第7步要调用过程mov(n-1,b,c,a),即第5、第6步),(把上面2个盘捆视为1个盘)。原有n个盘问题,可把n-1个盘捆在一起,同理可求解。
其中mov中的参数分别表示需移动的盘数、开始柱、终止柱与临时过渡柱,这种转换直到转入和盘数为0时才停止,因为这时已无盘可移了。
【参考程序】
Program P17_1;
var x,y,x:char;
n,k:integer;
Procedure mov(n:integer;a,c,b:char); {借用b,实现把n个盘片从a移动到c}
n
fac(n)
fac(n)
5
n*fac(n-1)
5*fac(4)
5*fac(4)
20
4(n-1)
4*fac(3)
4*fac(3)
24
3
3*fac(2)
3*fac(2)
6
2
2*fac(1)
2*fac(1)
2
1
1
1
1
先把因数推向极值1,然后再逐层退回来利用关系n*fac(n-1)得到最后结果
图17-4递归调用的过程
图17-4中左边部分表明了由于递归调用不断产生新的局部变量是保存在一个栈中,这些变量虽然同名,但各自独立,在逐层返回的过程中又是不断地从栈顶取出,直到取完。
从图17-4中可以看出,递归过程的执行总是一个过程体执行完,就带着本次执行的结果又进入另一轮过程执行。如此反复,不断深入。直到某次过程的执行遇到终止递归调用的条件成立时,则不再深入。而执行本次的过程体余下的部分,然后又返回到上一次调用的过程体,执行其余的部分。如此反复,直到回到起始位置上,才最终结束整个递归过程执行,得到相应的执行结果。
汉诺塔规则讲解
汉诺塔规则讲解汉诺塔(Hanoi)游戏是一种经典的递归算法应用,它最早由数学家帕斯卡于1883年发明,自此汉诺塔在数学及程序设计领域广受推崇。
该算法是一种古老的思想,可以用来解决众多的问题,其中最著名的便是现在众所周知的汉诺塔问题。
汉诺塔问题的描述如下:游戏中有三根柱子,标记为A、B、C,在A柱子上从上到下按大小顺序放置若干碟子(最多可有64个),每次只能移动一个碟子,且小碟子不能放置在大碟子之上。
目标是将碟子移动到柱子B或C,按大小顺序放置。
汉诺塔解决算法的基本原理是:如果要把n个碟子从A移动到C,那么首先把A上的n-1个碟子移动到B,然后把A上的最后一个碟子移动到C,最后把B上的n-1个碟子移动到C。
如果要把n-1个碟子从A移动到B,那么首先把A上的n-2个碟子移动到C,然后把A上的第n-1个碟子移动到B,最后把C上的n-2个碟子移动到B。
继续这种逻辑,我们可以分解出以下规则:(1)如果要把n个碟子从A移动到C,首先把A上的n-1个碟子移动到B,然后把A上的最后一个碟子移动到C,最后把B上的n-1个碟子移动到C。
(2)如果要把n-1个碟子从A移动到B,首先把A上的n-2个碟子移动到C,然后把A上的第n-1个碟子移动到B,最后把C上的n-2个碟子移动到B。
根据以上规则,我们可以确定n个碟子的移动路径,具体算法如下:第一步、当n==1时,移动碟子从A到C,完成任务;第二步、当n>1时,采用递归的思想,先把A上的n-1个碟子移动到B,然后把A上的第n个碟子移动到C,最后把B上的n-1个碟子移动到C;第三步、采用分治策略,就可以把一个大问题分解成小问题,然后逐个解决,完成最终的任务。
综上所述,汉诺塔问题应用分治策略和递归思想可以解决,其解决算法特点是将一个大问题分解成若干小问题,逐个解决,并且每次只能移动一个碟子,而且小碟子不能放在大碟子之上,最终完成任务。
此种算法极富创造性,能够运用于许多程序设计领域,是一种典范的程序设计、数学和思维的综合应用。
汉诺塔c语言讲解
汉诺塔c语言讲解
汉诺塔是一种经典的数学逻辑游戏,同时也是计算机科学中经典的递归算法示例之一。
在汉诺塔游戏中,我们有三个柱子,最初第一个柱子上排列着n个圆盘,它们呈金字塔形状。
我们的任务是把这些盘子一个一个地从第一个柱子移到第三个柱子上,同时保持它们原来的顺序。
C语言是一种流行的编程语言,它可以用来实现各种算法和游戏。
用C语言实现汉诺塔游戏就非常简单。
我们可以将汉诺塔的规则抽象为下面这段C语言代码:
void hanoi(int n, char a, char b, char c)
{
if (n == 1) {
printf("%c to %c\n", a, c);
} else {
hanoi(n-1, a, c, b);
printf("%c to %c\n", a, c);
hanoi(n-1, b, a, c);
}
}
这个函数接受四个参数,分别是表示盘子数目的n,以及三个柱子的标识符a、b和c。
它通过递归实现将n个盘子从a柱子移动到c柱子的过程。
每次调用hanoi()函数时,它都会将一个盘子从a柱子上取下,然后递归地将n-1个盘子从a移到b柱子上,最后将那个盘子从a 移到c柱子上。
这个算法非常简洁和优美,同时也能展示出递归算法的良好性质。
总之,用C语言实现汉诺塔游戏是一种非常有趣和有益的编程练习,可以提高我们的编程能力和算法思维水平。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汉诺塔C递归算法详细解答
程序如下:
void move(char x,char y){
printf("%c-->%c\n",x,y);
}
void hanoi(int n,char one,char two,char three){
/*将n个盘从one座借助two座,移到three座*/
if(n==1) move(one,three);
else{
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
}
}
main(){
int n;
printf("input the number of diskes:");
scanf("%d",&n);
printf("The step to moving %3d diskes:\n",n);
hanoi(n,'A','B','C');
}
Hanoi塔问题, 算法分析如下,设A上有n个盘子。
如果n=1,则将圆盘从A直接移动到C。
如果n=2,则:
(1)将A上的n-1(等于1)个圆盘移到B上;
(2)再将A上的一个圆盘移到C上;
(3)最后将B上的n-1(等于1)个圆盘移到C上。
如果n=3,则:
A)将A上的n-1(等于2,令其为n`)个圆盘移到B(借助于C),步骤如下:(1)将A上的n`-1(等于1)个圆盘移到C上。
(2)将A上的一个圆盘移到B。
(3)将C上的n`-1(等于1)个圆盘移到B。
B)将A上的一个圆盘移到C。
C)将B上的n-1(等于2,令其为n`)个圆盘移到C(借助A),步骤如下:(1)将B上的n`-1(等于1)个圆盘移到A。
(2)将B上的一个盘子移到C。
(3)将A上的n`-1(等于1)个圆盘移到C。
到此,完成了三个圆盘的移动过程。
从上面分析可以看出,当n大于等于2时,移动的过程可分解为三个步骤:第一步把A上的n-1个圆盘移到B上;第二步把A上的一个圆盘移到C上;第三步把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。
当n=3时,第一步和第三步又分解为类同的三步,即把n`-1个圆盘从一个针移到另一个针上,这里的n`=n-1。
Hanoi塔问题中函数调用时系统所做工作
一个函数在运行期调用另一个函数时,在运行被调用函数之前,系统先完成3件事:
①将所有的实参、返回地址等信息传递给被调用函数保存。
②为被调用函数的局部变量分配存储区;
③将控制转移到被调用函数的入口。
从被调用函数返回调用函数前,系统也应完成3件事:
①保存被调用函数的结果;
②释放被调用函数的数据区;
③依照被调用函数保存的返回地址将控制转移到调用函数。
当有多个函数构成嵌套调用时,按照“后调用先返回”的原则(LIFO),上述函数之间的信息传递和控制转移必须通过“栈”来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就为其在栈顶分配一个存储区,每当从一个函数退出时,就释放其存储区,因此当前运行函数的数据区必在栈顶。
堆栈特点:LIFO,除非转移或中断,堆栈内容的存或取表现出线性表列的性质。
正是如此,程序不要求跟踪当前进入堆栈的真实单元,而只要用一个具有自动递增或自动递减功能的堆栈计数器,便可正确指出最后一次信息在堆栈中存放的地址。
一个递归函数的运行过程类型于多个函数的嵌套调用,只是调用函数和被调用函数是同一个函数。
因此,和每次调用相关的一个重要的概念是递归函数运行的“层次”。
假设调用该递归函数的主函数为第0层,则从主函数调用递归函数为进入第1层;从第i层递归调用本函数为进入下一层,即i+1层。
反之,退出第i层递归应返回至上一层,即i-1层。
为了保证递归函数正确执行,系统需设立一个“递归工作栈”,作为整个递归函数运行期间使用的数据存储区。
每一层递归所需信息构成一个“工作记录”,其中包括所有实参、所有局部变量以及上一层的返回地址。
每进入一层递归,就产生一个新的工作记录压入栈顶。
每退出一层递归,就从栈顶弹出一个工作记录,则当前执行层的工作记录必是递归工作栈栈顶的工作记录,称这个记录为“活动记录”,并称指示活动记录的栈顶指针为“当前环境指针”。