汉诺塔的递归求解分析

合集下载

汉诺塔的递归算法

汉诺塔的递归算法

汉诺塔的递归算法1. 汉诺塔问题简介汉诺塔是一种经典的递归问题,常用于理解和展示递归算法的思想。

该问题由法国数学家爱德华·卢卡斯于19世纪初提出,得名于印度传说中一个传说故事。

现代汉诺塔问题由3个塔座和一些盘子组成,目标是将所有盘子从一个塔座上移动到另一个塔座上,遵循以下规则:1.一次只能移动一个盘子;2.大盘子不能放在小盘子上面。

2. 汉诺塔问题的递归解法汉诺塔问题的递归解法是一种简洁、优雅且高效的解决方案。

递归算法是一种将大问题划分为更小子问题的方法,通过递归地解决子问题来解决整个问题。

2.1. 基本思想以三个塔座A、B、C为例,假设有n个盘子需要从A移动到C。

递归算法的基本思想如下:1.将n个盘子分成两部分:最底下的一个盘子和上面的n-1个盘子;2.将上面的n-1个盘子从塔座A移动到塔座B,目标塔座为C;3.将最底下的一个盘子从塔座A移动到塔座C;4.将塔座B上的n-1个盘子移动到塔座C,目标塔座为A。

2.2. 递归实现递归解决汉诺塔问题的关键在于理解递归的调用和返回过程。

具体的递归实现如下:def hanoi(n, a, b, c):# n表示盘子的数量,a、b、c表示3个塔座if n == 1:print("Move disk from", a, "to", c)else:hanoi(n-1, a, c, b)print("Move disk from", a, "to", c)hanoi(n-1, b, a, c)# 调用递归函数hanoi(3, 'A', 'B', 'C')上述代码中,当n等于1时,直接将盘子从塔座A移动到塔座C。

否则,递归地将上面的n-1个盘子从塔座A移动到塔座B,然后将最底下的一个盘子从A移动到C,最后再将塔座B上的n-1个盘子移动到塔座C。

汉诺塔递归的过程

汉诺塔递归的过程

汉诺塔递归的过程
汉诺塔递归的过程可以分为以下几个步骤:
1. 基本情况:如果只有一个盘子需要移动,直接将这个盘子从起始柱子移动到目标柱子即可。

2. 递归步骤:将上面的n-1 个盘子从起始柱子通过辅助柱子移动到目标柱子,然后将剩下的最大的盘子直接从起始柱子移动到目标柱子,最后,将之前移动到辅助柱子的n-1 个盘子通过起始柱子移动到目标柱子。

递归的过程中,每一次移动实际上都是在解决一个更小的汉诺塔问题。

具体来说,每当你移动一个盘子时,你实际上是在解决一个有n-1 个盘子的汉诺塔问题,直到只剩下一个盘子,然后再反向操作。

例如,假设有三个盘子(A、B、C),汉诺塔的解法如下:
- 将A(最小盘子)从A 移动到C(辅助柱子)。

- 将B(中等盘子)从A 移动到A(起始柱子)。

- 将A 从C 移动到B(目标柱子)。

- 将B 从A 移动到C。

- 将A 从C 移动到A。

- 将B 从C 移动到B。

- 最后,将A 从A 移动到B。

在这个过程中,每次移动都是在解决一个更小的问题,直到最终解决整个汉诺塔问题。

汉诺塔问题数学解法

汉诺塔问题数学解法

汉诺塔问题数学解法汉诺塔问题是一个经典的数学问题,它的解法是基于递归的。

假设有n个圆盘,编号从1到n,初始时都放置在A柱子上,目标是将这些圆盘移动到C柱子上。

移动过程中必须遵守以下规则:每次只能移动一个圆盘;大圆盘不能放在小圆盘上面。

解题步骤如下:1. 如果n=1,则直接将编号为1的圆盘从A柱子移动到C柱子上,移动完毕。

2. 如果n>1,先将n-1个圆盘从A柱子通过C柱子移动到B柱子上。

此时A柱子上只剩下编号为n的圆盘。

3. 将编号为n的圆盘从A柱子移动到C柱子上,移动完毕。

4. 最后将B柱子上的n-1个圆盘通过A柱子移动到C柱子上。

可以看出,将n个圆盘移动到C柱子上的步骤可以分解为以下子问题:1. 将n-1个圆盘从A柱子通过C柱子移动到B柱子上。

2. 将编号为n的圆盘从A柱子移动到C柱子上。

3. 将n-1个圆盘从B柱子通过A柱子移动到C柱子上。

可以使用递归的方法来解决汉诺塔问题。

具体代码如下所示:```def hanoi(n, A, B, C):if n == 1:print("Move disk", n, "from", A, "to", C)else:hanoi(n-1, A, C, B)print("Move disk", n, "from", A, "to", C)hanoi(n-1, B, A, C)n = 3hanoi(n, '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```这样,就完成了将3个圆盘从A柱子移动到C柱子的全部步骤。

汉诺塔问题数学解法

汉诺塔问题数学解法

汉诺塔问题数学解法
一、建立递归模型
汉诺塔问题是一个经典的递归问题,可以通过建立递归模型来求解。

递归模型的基本思想是将问题分解为更小的子问题,然后通过对子问题的求解来得到原问题的解。

二、定义变量
在汉诺塔问题中,我们可以定义以下变量:
n:表示盘子的数量;
A、B、C:表示三个柱子,其中A柱子是起始柱子,B 柱子是辅助柱子,C柱子是目标柱子;
m:表示当前需要移动的盘子数量。

三、递归关系
汉诺塔问题的递归关系可以表示为:
将m个盘子从A移动到C,需要先将m-1个盘子从A移动到B,然后将最后一个盘子从A移动到C,最后将m-1个盘子从B移动到C。

将m个盘子从A移动到B,需要先将m-1个盘子从A移动到C,然后将最后一个盘子从A移动到B,最后将m-1个盘子从C移动到B。

将m个盘子从B移动到C,需要先将m-1个盘子从B移动到A,然后将最后一个盘子从B移动到C,最后将m-1个盘子从A移动到C。

四、寻找规律
通过观察递归关系,我们可以发现以下规律:
每次移动都需要经过三个柱子,即起始柱子、辅助柱子和目标柱子;
每次移动都需要将n-1个盘子从起始柱子移动到辅助柱子,然后将最后一个盘子从起始柱子移动到目标柱子,最后将n-1个盘子从辅助柱子移动到目标柱子;
每次移动都需要将n-1个盘子从起始柱子移动到辅助柱子,然后将最后一个盘子从起始柱子移动到目标柱子,最后将n-1个盘子从辅助柱子移动到目标柱子。

五、验证解决方案
通过以上规律,我们可以得到汉诺塔问题的解法。

为了验证解法的正确性,我们可以使用递归函数来实现解法,并使用测试数据来验证解法的正确性。

汉诺塔递归算法及详解

汉诺塔递归算法及详解

汉诺塔递归算法及详解
汉诺塔(Tower of Hanoi)是一个经典的数学谜题和递归问题。

它由三个塔杆和一些不同大小的圆盘组成,开始时圆盘按从大到小的顺序叠放在一个塔杆上。

目标是将所有圆盘从起始塔杆移动到目标塔杆上,同时遵守以下规则:
1. 一次只能移动一个圆盘。

2. 任何时刻,大的圆盘不能放在小的圆盘上面。

递归算法是解决汉诺塔问题的常用方法。

其基本思想是将问题分解为较小规模的子问题,然后通过递归地解决子问题来解决原问题。

以下是汉诺塔递归算法的详解:
1. 如果只有一个圆盘需要移动,则直接将圆盘从起始塔杆移动到目标塔杆上。

2. 如果有多个圆盘需要移动,则按以下步骤进行操作:
- 将除最下方的圆盘以外的上方圆盘从起始塔杆移动到辅助塔杆上。

这可以通过递归调用解决较小规模的子问题来实现,即将上方圆盘从起始塔杆移动到目标塔杆上(目标塔杆作为新的辅助塔杆)。

- 然后将最下方的圆盘从起始塔杆直接移动到目标塔杆上。

- 最后,将辅助塔杆上的所有圆盘移动到目标塔杆上,这可以通过递归调用解决较小规模的子问题来实现,即将上方圆盘从辅助塔杆移动到起始塔杆上(起始塔杆作为新的目标塔杆)。

通过递归地应用以上步骤,就可以实现将所有圆盘从起始塔杆移动到目标塔杆上的操作。

数据结构求解汉诺塔问题的递归算法

数据结构求解汉诺塔问题的递归算法

数据结构求解汉诺塔问题的递归算法汉诺塔问题是一个经典的数学问题,它可以通过递归算法来求解。

在这个问题中,我们需要将一堆盘子从一个柱子移动到另一个柱子,同时遵守以下规则:一次只能移动一个盘子,大盘子不能放在小盘子上面。

为了解决这个问题,我们可以使用数据结构中的栈来模拟柱子的堆叠。

我们可以将每个柱子表示为一个栈,每个盘子表示为一个元素。

初始时,所有的盘子都在第一个柱子上,我们需要将它们移动到第三个柱子上。

下面是求解汉诺塔问题的递归算法的伪代码:```1. 定义一个函数hanoi,接受参数n、起始柱子A、辅助柱子B、目标柱子C2. 如果n等于1,则直接将盘子从A移动到C3. 否则,将n-1个盘子从A移动到B,借助C作为辅助柱子4. 将第n个盘子从A移动到C5. 将n-1个盘子从B移动到C,借助A作为辅助柱子```接下来,我们来详细解释一下这个算法。

首先,我们定义了一个函数hanoi,它接受四个参数:n表示盘子的数量,起始柱子A、辅助柱子B和目标柱子C。

在函数内部,我们首先判断如果n等于1,那么我们直接将盘子从A移动到C即可。

这是递归算法的终止条件。

如果n大于1,我们需要将n-1个盘子从A移动到B,借助C作为辅助柱子。

这一步是通过递归调用hanoi函数来实现的。

在递归调用中,我们将n-1作为新的盘子数量,A作为起始柱子,B作为目标柱子,C作为辅助柱子。

接下来,我们将第n个盘子从A移动到C。

这一步是直接操作的,不需要递归调用。

最后,我们需要将n-1个盘子从B移动到C,借助A作为辅助柱子。

同样地,我们通过递归调用hanoi函数来实现这一步。

在递归调用中,我们将n-1作为新的盘子数量,B作为起始柱子,C作为目标柱子,A作为辅助柱子。

通过这样的递归调用,我们可以将所有的盘子从起始柱子A移动到目标柱子C,同时遵守汉诺塔问题的规则。

总结起来,数据结构中的栈可以很好地模拟汉诺塔问题中的柱子堆叠,而递归算法则可以很好地解决这个问题。

用递归算法实现汉诺塔问题。

用递归算法实现汉诺塔问题。

用递归算法实现汉诺塔问题。

汉诺塔问题是一个经典的递归问题,它涉及到的思维方式是分治法,而递归则是实现分治法的一种方式。

要解决汉诺塔问题,我们需要了解其规则和思路。

汉诺塔游戏的规则如下:1. 有三根柱子A、B、C,开始时A柱上有一些大小不等的圆盘,按大小从上到下依次叠放。

2. 目标是把A柱上的圆盘全部移到C柱上,可以借助B柱。

3. 每次只能移动一个圆盘,且大圆盘不能叠在小圆盘上。

解决汉诺塔问题的思路:1. 对于每个规模为n的问题,我们可以分解为三个步骤:将A柱上的n-1个圆盘移到B柱上,将A柱上的最大圆盘移到C柱上,最后将B柱上的n-1个圆盘移到C柱上。

2. 每个步骤都是一个规模为n-1的子问题,因此可以使用递归来解决。

接下来,我们用递归算法实现汉诺塔问题。

```pythondef hanoi(n, A, B, C):"""递归函数hanoi参数:n:表示A柱上的圆盘数量A:表示原柱子B:表示辅助柱子C:表示目标柱子"""if n == 1: # 如果只有一个圆盘,直接从A柱移到C柱print(f"将第1个圆盘从 {A} 移动到 {C}")returnelse:# 将A柱上的n-1个圆盘移到B柱上hanoi(n-1, A, C, B)# 将A柱上的最大圆盘移到C柱上print(f"将第{n}个圆盘从 {A} 移动到 {C}")# 将B柱上的n-1个圆盘移到C柱上hanoi(n-1, B, A, C)# 测试n = 3 # 圆盘数量为3hanoi(n, 'A', 'B', 'C')```对于圆盘数量为3的情况,我们可以得到以下步骤:将第1个圆盘从 A 移动到 C将第2个圆盘从 A 移动到 B将第1个圆盘从 C 移动到 B将第3个圆盘从 A 移动到 C将第1个圆盘从 B 移动到 A将第2个圆盘从 B 移动到 C将第1个圆盘从 A 移动到 C通过递归的方式,我们可以解决汉诺塔问题并打印出每一步的移动过程。

汉诺塔问题实验报告

汉诺塔问题实验报告
1.实验目的: 通过本实验,掌握复杂性问题的分析方法,了解汉诺塔
游戏的时间复杂性和空间复杂性。 2.问题描述:
汉诺塔问题来自一个古老的传说:在世界刚被创建的时候有 一座钻石宝塔(塔 A),其上有 64 个金碟。所有碟子按从大到小的次 序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔(塔 B 和 塔 C)。从世界创始之日起,婆罗门的牧师们就一直在试图把塔 A 上的碟子移动到塔 C 上去,其间借助于塔 B 的帮助。每次只能移 动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。 当牧师们完成任务时,世界末日也就到了。 3.算法设计思想:
8、总结
5
缓存大小
通过对汉诺塔算法的分析让我更清楚的认识到了不同的算法对 程序性能的影响,也让我明白掌握了算法将会有助于提高软件的开 发。
6
2)Hanoi 塔问题递归程序的复杂度分析
① 运行 hanoi 程序的时间
程序 hanoi.c 在硬件环境为赛扬 400MHz、内存 128M 的计算平台 (不同机器运行时间有一定差别)运行,可得出如下时间结果:
盘子数
时间结果
<=12 个
<=1 秒
14 个
2秒
16 个
13 秒
20 个
204 秒
② 时间复杂度
自定义头文件 :#pragma once
#include "targetver.h" #include <stdio.h> #include <tchar.h>
结果如下:
2
6.递归应用中的 Hanoi 塔问题分析 1)Hanoi 塔问题中函数调用时系统所做工作
一个函数在运行期调用另一个函数时,在运行被调用函数之前,系 统先完成 3 件事:

汉诺塔递归算法流程

汉诺塔递归算法流程

汉诺塔递归算法的流程可以概括为以下几个步骤:
初始化:首先,你需要确定起始塔、目标塔和辅助塔。

通常,起始塔包含所有盘子,目标塔是空的,辅助塔是用来临时放置盘子的。

递归调用:对于当前的起始塔,你需要递归地将所有盘子从起始塔移动到辅助塔,然后再将所有盘子从辅助塔移动到目标塔。

移动盘子:在递归调用中,你需要将当前最小的盘子从一个塔移动到另一个塔。

然后,你将剩余的盘子移动到当前最小的盘子的塔,这个过程将递归地重复下去,直到所有盘子都被移动到目标塔。

汉诺塔递归算法及详解

汉诺塔递归算法及详解

汉诺塔递归算法及详解汉诺塔(Hanoi Tower)是一种数学谜题,由法国数学家Édouard Lucas在19世纪中期提出。

这个谜题由三根柱子和一组圆盘组成,圆盘从上到下按照从小到大的顺序放置在柱子上。

问题的目标是将所有圆盘从一个柱子移动到另一个柱子,每次只能移动一个圆盘,并且不能将大的圆盘放在小的圆盘上面。

解决汉诺塔问题的一种常见方法是使用递归算法。

递归是一种数学和计算机科学中常见的方法,通过将复杂的问题分解为更小的相同问题的子问题来解决。

汉诺塔的递归算法主要包含以下步骤:1.将N-1个圆盘从起始柱子移动到中间柱子上,这可以通过将起始柱子作为源柱子,中间柱子作为辅助柱子,目标柱子为空柱子来实现。

这个步骤可以通过递归调用来实现,将起始柱子作为源柱子,中间柱子作为辅助柱子,目标柱子作为空柱子。

2.将第N个圆盘从起始柱子移动到目标柱子上。

3.将N-1个圆盘从中间柱子移动到目标柱子上,这可以通过将中间柱子作为源柱子,目标柱子作为辅助柱子,起始柱子作为空柱子来实现。

这个步骤可以通过递归调用来实现,将中间柱子作为源柱子,目标柱子作为辅助柱子,起始柱子作为空柱子。

下面是一个示例代码,使用递归算法解决汉诺塔问题:```pythondef hanoi(n, source, target, auxiliary):if n > 0:#将N-1个圆盘从起始柱子移动到中间柱子hanoi(n-1, source, auxiliary, target)#将第N个圆盘从起始柱子移动到目标柱子print("Move disk", n, "from", source, "to", target)#将N-1个圆盘从中间柱子移动到目标柱子hanoi(n-1, auxiliary, target, source)#测试n=3hanoi(n, 'A', 'C', 'B')```上述代码中,`hanoi(`函数接受四个参数:圆盘的数量n,起始柱子source,目标柱子target和辅助柱子auxiliary。

汉诺塔实验报告

汉诺塔实验报告

一、实验目的1. 理解汉诺塔问题的基本原理。

2. 掌握分治算法在解决汉诺塔问题中的应用。

3. 通过编程实现汉诺塔问题的递归与非递归解法。

4. 分析汉诺塔问题的移动次数,并探讨优化方案。

二、实验原理汉诺塔问题是一个经典的递归问题,描述为:有n个大小不同的圆盘,它们分别放在三根柱子上,初始状态为第1根柱子从上到下依次排列。

要求按照以下规则将所有圆盘移动到第3根柱子上:1. 一次只能移动一个圆盘。

2. 任何时候,在某一根柱子上的圆盘都必须是按照从上到下依次递减的顺序排列。

3. 不能将一个较大的圆盘放在一个较小的圆盘上面。

汉诺塔问题可以通过分治法来解决。

分治法的基本思想是将大问题分解成小问题,分别解决小问题,最后将小问题的解合并成大问题的解。

对于汉诺塔问题,我们可以将其分解为以下三个子问题:1. 将n-1个圆盘从第1根柱子移动到第2根柱子。

2. 将第n个圆盘从第1根柱子移动到第3根柱子。

3. 将n-1个圆盘从第2根柱子移动到第3根柱子。

通过递归地解决这三个子问题,我们可以得到汉诺塔问题的解。

三、实验内容1. 递归解法我们可以使用递归函数来实现汉诺塔问题的递归解法。

以下是C语言实现的示例代码:```c#include <stdio.h>void hanoi(int n, char from, char to, char aux) {if (n == 1) {printf("Move disk 1 from %c to %c\n", from, to);return;}hanoi(n - 1, from, aux, to);printf("Move disk %d from %c to %c\n", n, from, to);hanoi(n - 1, aux, to, from);}int main() {int n;printf("Enter the number of disks: ");scanf("%d", &n);hanoi(n, 'A', 'C', 'B');return 0;}```2. 非递归解法除了递归解法,我们还可以使用栈来实现汉诺塔问题的非递归解法。

汉诺塔问题是用什么方法求解的

汉诺塔问题是用什么方法求解的

汉诺塔问题是用什么方法求解的
汉诺塔问题的求解是需要借助于递归方法来实现的。

1、就是我们不管前面有多少个盘子,就是需要将A上面除了最大的盘子之外的所有n-1个盘子借助C移动到B。

2、然后移动A柱子上最大的盘子到C柱子(A->C),这时候,就无需再考虑最大盘子的移动了,就是剩下的n-1个盘子,怎么把他们从B移动到C上面。

3、我们需要借助的柱子变成了A,因为A上面没有盘子了,问题变成了B柱子借助A柱子,将n-1个盘子移动到C柱子。

计划能力决定圆盘移动顺序
关于汉诺塔问题解决的一个最主要的观点认为,完成汉诺塔任务时要对圆盘的移动顺序进行预先计划和回顾性计划活动。

当问题呈现后,在开始第一步的移动之前,大多数被试都会根据设定好的目标状态,对圆盘的移动顺序进行预先计划。

以决定圆盘的移动顺序,但是这种计划能力的作用可能会受到问题难度的影响。

hanoi塔递归算法

hanoi塔递归算法

hanoi塔递归算法Hanoi塔问题是一道经典的递归问题,它源于印度传说中的一个古老故事。

这个故事讲述了一个寺庙里有三根柱子,其中一根柱子上有64个盘子,从小到大依次放置。

寺庙里的僧人们每天都要把这些盘子从一根柱子移动到另一根柱子上,并且规定在移动过程中不能把大盘子放在小盘子的上面。

这个问题的挑战在于如何用最少次数将所有盘子从起始柱移动到目标柱。

1. 问题描述假设有三根柱子,分别为A、B、C,其中A柱上有n个圆盘,大小依次递增。

现在需要将A柱上的所有圆盘移动到C柱上,可以借助B柱作为中转站,但是需要满足以下条件:1. 每次只能移动一个圆盘;2. 圆盘可以放置在空柱或者比它大的圆盘上;3. 需要保证始终满足第2条规则。

求解该问题所需最少步骤。

2. 递归算法实现Hanoi塔问题可以使用递归算法来进行求解。

递归算法的基本思路是将一个大问题分解成若干个小问题,通过不断递归调用函数来解决这些小问题。

对于Hanoi塔问题,我们可以将其分解成三个步骤:1. 将n-1个圆盘从A柱移动到B柱;2. 将第n个圆盘从A柱移动到C柱;3. 将n-1个圆盘从B柱移动到C柱。

这样一来,原问题就被分解成了三个规模更小的子问题。

对于每一个子问题,我们可以继续按照同样的方式进行分解,直到规模变得足够小,可以直接求解为止。

下面是Hanoi塔递归算法的实现代码:```void hanoi(int n, char A, char B, char C) {if (n == 1) {cout << "Move disk " << n << " from " << A << " to " << C << endl;} else {hanoi(n - 1, A, C, B);cout << "Move disk " << n << " from " << A << " to " << C << endl;hanoi(n - 1, B, A, C);}}```其中,参数n表示当前需要移动的圆盘数量;参数A、B、C表示三根柱子的名称。

c++汉诺塔问题递归算法

c++汉诺塔问题递归算法

c++汉诺塔问题递归算法汉诺塔问题是经典的递归问题,它可以帮助我们理解和掌握递归算法的思想。

在C++中,我们可以通过递归来解决汉诺塔问题。

汉诺塔问题的描述如下:有三根柱子A、B、C,A柱子上有n 个盘子,盘子的大小不一,大的在下,小的在上。

现在要将A 柱子上的盘子移动到C柱子上,并且每次只能移动一个盘子,并且大的盘子不能放在小的盘子上面。

要求通过借助柱子B来实现移动。

下面我们先给出解决汉诺塔问题的递归代码:```cpp#include <iostream>void hanoi(int n, char A, char B, char C) {if (n == 1) {std::cout << "Move disk 1 from " << A << " to " << C << std::endl;return;}hanoi(n - 1, A, C, B);std::cout << "Move disk " << n << " from " << A << " to " << C << std::endl;hanoi(n - 1, B, A, C);}int main() {int n = 3; // 盘子的个数hanoi(n, 'A', 'B', 'C');return 0;}```上面的代码使用了递归的思想来解决汉诺塔问题。

函数`hanoi()`接受四个参数,n表示盘子的个数,A、B、C表示三根柱子的名称。

当n等于1时,表示只有一个盘子需要移动,直接将它从A柱子移动到C柱子即可。

当n大于1时,我们可以把问题简化为两个步骤:将n-1个盘子从A柱子通过借助C柱子移动到B柱子,然后将最后一个盘子从A柱子移动到C柱子,最后将n-1个盘子从B柱子通过借助A柱子移动到C 柱子。

采用递归算法求解汉诺塔问题的三个步骤

采用递归算法求解汉诺塔问题的三个步骤

一、问题描述汉诺塔问题是一个源自印度的数学问题,它由法国数学家爱德华·卢卡斯在1883年首次提出。

问题的描述如下:有三根柱子A、B、C,A 柱上穿有由小到大的64个圆盘,要求将所有圆盘从A柱移动到C柱上,并且要求在移动过程中始终保持较大的圆盘在下、较小的圆盘在上。

在移动的过程中可以借助B柱。

二、递归算法解决汉诺塔问题的三个步骤1. 确定递归的基本情况:当只有一个圆盘需要移动时,直接将圆盘从A柱移动到C柱即可。

2. 分解子问题:当有n个圆盘需要移动时,可以将其分解为三个子问题:- 将n-1个圆盘从A柱移动到B柱- 将最大的圆盘从A柱移动到C柱- 将n-1个圆盘从B柱移动到C柱3. 递归调用:对上述三个子问题分别递归调用上述步骤,直到递归的基本情况。

三、递归算法求解汉诺塔问题的Python代码实现'''def hanoi(n, source, target, auxiliary):if n == 1:print(f"将圆盘{1}从{source}柱移动到{target}柱")else:hanoi(n-1, source, auxiliary, target)print(f"将圆盘{n}从{source}柱移动到{target}柱")hanoi(n-1, auxiliary, target, source)hanoi(3, 'A', 'C', 'B')'''四、递归算法求解汉诺塔问题的实例演示假设有3个圆盘(n=3),初始状态是所有圆盘都在A柱上,目标状态是所有圆盘都在C柱上。

根据递归算法,我们可以依次执行以下步骤:1. 将2个圆盘从A柱移动到B柱- 将圆盘1从A柱移动到C柱- 将圆盘2从A柱移动到B柱- 将圆盘1从C柱移动到B柱2. 将最大的圆盘3从A柱移动到C柱3. 将2个圆盘从B柱移动到C柱- 将圆盘1从B柱移动到A柱- 将圆盘2从B柱移动到C柱- 将圆盘1从A柱移动到C柱通过上述步骤,我们成功地将3个圆盘从A柱移动到C柱上,且满足汉诺塔问题的要求。

汉诺塔游戏递归

汉诺塔游戏递归
【分析】打开压缩包,运行里面的程序HANOI.EXE
先考虑简单情形。如果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中可以看出,递归过程的执行总是一个过程体执行完,就带着本次执行的结果又进入另一轮过程执行。如此反复,不断深入。直到某次过程的执行遇到终止递归调用的条件成立时,则不再深入。而执行本次的过程体余下的部分,然后又返回到上一次调用的过程体,执行其余的部分。如此反复,直到回到起始位置上,才最终结束整个递归过程执行,得到相应的执行结果。

汉诺塔游戏递归

汉诺塔游戏递归
如在汉诺塔游戏中,按照移动原则,将n个盘从A杆移动到C杆需要移动盘的次数是2的n次幂减1,那么64个盘移动次数就是18 446 744 073 709 511 645,近19亿亿次。这是一个天文数字,即使一台功能很强的现代计算机来解汉诺栽塔问题,恐怕也需要很长的时间,因此要想得到结果,在运行程序时,输入的n可不能太大。据说布拉玛婆罗门圣庙的僧侣声称,汉诺塔游戏结束就标志着世界末日的到来,现在看来确实是有道理的。因为如果每秒移动一次,64个盘则大约需近5800亿年,而据科学家以能源角度推算,太阳系的寿命只不过150亿年而已。
qiu(n); {调用子程序}
writeln(s:2:0)
end.
展示实力
万炽洋的程序:
1、某人写了n封信和n个信封,结果所有信都装错信封。求所有的信都装错信封共有多少种不同的情况。
2、楼梯有n阶台阶,上楼可以一步上一阶,也可以一步上二阶。请用递归方法编程计算共有多少种不同的走法。
3、用递归方法方法完成:有52张牌,使它们全部正面朝上,第一轮是从第2张开始,凡是2的倍数位置上的牌翻成正面朝下;第二轮从第三张牌开始,凡是3的倍数位置上的牌以,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张牌开始,凡是4的倍数位置上的牌按上面相同规则翻转,从此类推,直到第一张要翻的牌超过52为止。统计最后有几张牌正面朝上,以及它们的位置号。
〖分析〗读入一个字符,判断是否为"#"号,如果不是就继续读入,即可以调用程序本身。如果是“#”,则输出字符
〖参考程序〗
program P17_4;
procedure rever;
var c:char;
begin
read(c);
if c<>'#' then rever; {递归调用的地方,下一次调用会分配新单元c}

汉诺塔递归算法

汉诺塔递归算法

汉诺塔递归算法
1. 简介
汉诺塔(Hanoi Tower)是一种经典的数学问题,它由法国数学家Edouard Lucas于1883年引入,并以法国一个寺庙的名字命名。

汉诺塔问题是一个经典的递归问题,它可以通过递归算法来解决。

2. 问题描述
汉诺塔问题的问法如下:
有三根柱子A、B、C,初始时柱子A上有若干个大小不同的盘子,按照从小到大的顺序从上往下叠放。

现在需要将这些盘子从柱子A移动到柱子C,移动过程中需要满足以下条件:
1.每次只能移动一个盘子;
2.每根柱子上的盘子都必须保持原有的从小到大的顺序。

问:如何才能将这些盘子从柱子A移动到柱子C,并且满足以上条件?
3. 解决方法
汉诺塔问题的解决方法之一是使用递归算法。

递归算法是一种通过函数自身调用来解决问题的方法。

对于汉诺塔问题,可以通过以下的递归算法来解决:
步骤
1.如果只有一个盘子需要移动,直接将盘子从柱子A移动到柱子C即可;
2.如果有多个盘子需要移动,将其分成三个步骤:
1.将n-1个盘子从柱子A移动到柱子B;
2.将最大的盘子从柱子A移动到柱子C;
3.将n-1个盘子从柱子B移动到柱子C。

递归实现
以下是使用递归实现汉诺塔问题的Python代码:
```python def hanoi(n, A, B, C): if n == 1: print(f。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

汉诺塔的递归求解分析学完函数,就马上出了道经典的汉诺塔来,书里说是把递归提前拿来研究学习了,这题目实在是把我弄晕了。

几天都在时时想这个题目。

递归是数学归纳法的逆过程。

递归函数是直接或通过另一个函数间接调用自己的函数。

C语言的特点就是允许函数的递归调用。

如果一个问题要用递归解决,得符合以下的条件:1,该问题要能转换成一个新问题,而新问题的解决方法要和原来的问题相同,只是复杂度有所减少而已。

既是要有一定的规律。

如求n!。

2、这个问题当简单到一定程度就可以解决,而不用再继续简化。

(即需要一个结束递归的条件。

否则无限的递归下去,最终会导致系统资源枯竭系统崩溃)。

3、问题用其他方法解决非常困难或不如用递归解决来的简单,(所有递归能解决的问题都能用迭代{非递归}来解决)这个条件是非必要的,但人总需要简单。

?要用递归解决问题,我们必须分析下列问题:1、递归的参数,用递归解决的问题通常都比较复杂,规模比较大,要找出决定递归复杂度,规模的参数,比如n!,决定的递归复杂度、规模的就是n。

2、找出递归结束的标志,没有递归结束的条件,将无限循环。

造成的后果是严重的。

3、找出递归的通式,才可以进一步简化问题。

(通常这是比较困难的)(比如:n!的通式就是n*(n-1)!,而且是可以不断简化直到到达结束递归的边界值)???一般的格式是:?if 结束条件1表达式1(赋予边界值1)else if 结束条件2表达式2(赋予边界值2)...else递归的解决问题的通式。

??汉诺塔的问题;这个问题对于我这个初学者来说,确实棘手,对于执行的步骤很不理解,虽然递归不用去了解执行的步骤的。

但是,不用去了解不等同于不了解。

一个庙里有三个柱子,第一个有64个盘子,从上往下盘子越来越大。

要求庙里的老和尚把这64个盘子全部移动到第三个柱子上。

移动的时候始终只能小盘子压着大盘子。

1、此时老和尚(后面我们叫他第一个和尚)觉得很难,所以他想:要是有一个人能把前63个盘子先移动到第二个柱子上,我再把最后一个盘子直接移动到第三个柱子,再让那个人把刚才的前63个盘子从第二个柱子上移动到第三个柱子上,我的任务就完成了,简单。

所以他找了比他年轻的和尚(后面我们叫他第二个和尚)(呵呵,倚老卖老),命令:①你把前63个盘子移动到第二柱子上②在我自己把第64个盘子一道第三个柱子上后③你把前63个盘子移动到第三柱子上2、第二个和尚接了任务,也觉得很难,所以他也和第一个和尚一样想:要是有一个人能把前62个盘子先移动到第三个柱子上,我再把最后一个盘子直接移动到第二个柱子,再让那个人把刚才的前62个盘子从第三个柱子上移动到第三个柱子上,我的任务就完成了,简单。

所以他也找了比他年轻的和尚(后面我们叫他第三和尚)(呵呵,又倚老卖老),命令:①你把前62个盘子移动到第三柱子上②在我自己把第63个盘子一道第二个柱子上后③你把前62个盘子移动到第二柱子上3、第三个和尚接了任务,又把移动前61个盘子的任务依葫芦话瓢的交给了第四个和尚,等等递推下去,直到把任务交给了第64个和尚为止(估计第64个和尚很郁闷,没机会也命令下别人,因为到他这里盘子已经只有一个了)。

4、到此任务下交完成,到各司其职完成的时候了。

?完成回推了:第64个和尚移动第1个盘子,把它移开,然后第63个和尚移动他给自己分??配的第2个盘子。

第64个和尚再把第1个盘子移动到第2个盘子上。

到这里第64个和尚的任务完成,第63个和尚完成了第62个和尚交给他的任务的第一步。

从上面可以看出,只有第64个和尚的任务完成了,第63个和尚的任务才能完成,只有第2个和尚—第64个和尚的任务完成后,第1个和尚的任务才能完成。

这是一个典型的递归问题。

?现在我们以有3个盘子来分析:?第1个和尚命令:㈠第2个和尚你先把第一柱子前2个盘子移动到第二柱子。

(借助第三个柱子)㈡第1个和尚我自己把第一柱子最后的盘子移动到第三柱子。

㈢第2个和尚你把前2个盘子从第二柱子移动到第三柱子。

很显然,第㈡步很容易实现(哎,人总是自私地,把简单留给自己,困难的给别人)其中第㈠步。

第2个和尚他有2个盘子,他就命令:①第3个和尚你把第一柱子第1个盘子移动到第三柱子。

(借助第二柱子)②第2个和尚我自己把第一柱子第2个盘子移动到第二柱子上。

③第3个和尚你把第1个盘子从第三柱子移动到第二柱子。

同样,第步很容易实现,但第3个和尚他只需要移动1个盘子,所以他也不用在下派任务了。

(注意:这就是停止递归的条件,也叫边界值)第㈢步可以分解为,第2个和尚还是有2个盘子,命令:①第3个和尚你把第二柱子上的第1个盘子移动到第一柱子。

②第2个和尚我把第2个盘子从第二柱子移动到第三柱子。

③第3个和尚你把第一柱子上的盘子移动到第三柱子。

分析组合起来就是:1-->3 1-->2 3-->2 1-->3 2-->1 2-->3 1-->3共需要七步。

如果是4个盘子,则第一个和尚的命令中第1步和第3步各有3个盘子,所以各需要7步,共14步,再加上第1个和尚的1步,所以4个盘子总共需要移动7+1+7=15步,同样,5个盘子需要15+1+15=31步,6个盘子需要31+1+31=64步……由此可以知道,移动n 个盘子需要(2的n次方)--1步。

?从上面整体综合分析可知把n个盘子从1座(相当第一柱子)移到3座(相当第三柱子):(1)把1座上(n-1)个盘子借助3座移到2座。

(2)把1座上第n个盘子移动3座。

(3)把2座上(n-1)个盘子借助1座移动3座。

?下面用hanoi(n,a,b,c)表示把1座n个盘子借助2座移动到3座。

很明显,(1)步上是 hanoi(n-1,1,3,2)(2)步上是hanoi(n-1,2,1,3)????下面便是代码:?#include<stdio.h>static long int m=1;/*用来计算移动步骤步数,静态变量才能不断叠加*/void hanoi(int n,int a,int b,int c){if(n==1){printf("(%d) %d-->%d/n",m,a,c);m++;}else{hanoi(n-1,a,c,b);printf("(%d) %d-->%d/n",m,a,c);/*只有当上一句得到结果,它才会执行*/m++;hanoi(n-1,b,a,c);}}main(){int d;printf("Enter the hanoi shu:");scanf("%d",&d);hanoi(d,1,2,3);return 0;}?执行:Enter the hanoi shu: 3(1)1-->3(2)1-->2(3)3-->2(4)1-->3(5)2-->1(6)2-->3(7)1-->3这里可能有个疑问:移动n-1个盘子确实是上面的步骤,但移动n-2的时候就不一样了啊?hanoi(n-1,a,c,b);printf("(%d) %d-->%d/n",m,a,c);/*只有当上一句得到结果,它才会执行*/m++;hanoi(n-1,b,a,c);?其实每一次调用hanoi(n,a,b,c)时a,b,c的值都不同。

如hanoi(n,1,2,3)时a=1,b=2,c=3.hanoi(n-1,a,c,b);{a=1,b=2,c=3}就是hanoi(n-1,1,3,2);所以调用的就是1-->2再次调用成了hanoi(n-2,a,c,b){a=1,b=3,c=2}就是hanoi(n-2,1,2,3);所以调用的就是,1-->3;每一次都能不断自动改变。

?Hanoi塔问题中函数调用时系统所做工作?一个函数在运行期调用另一个函数时,在运行被调用函数之前,系统先完成3件事:①将所有的实参、返回地址等信息传递给被调用函数保存。

②为被调用函数的局部变量分配存储区;③将控制转移到被调用函数的入口。

?从被调用函数返回调用函数前,系统也应完成3件事:①保存被调用函数的结果;②释放被调用函数的数据区;③依照被调用函数保存的返回地址将控制转移到调用函数。

当有多个函数构成嵌套调用时,按照“后调用先返回”的原则(LIFO),上述函数之间的信息传递和控制转移必须通过“栈”来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就为其在栈顶分配一个存储区,每当从一个函数退出时,就释放其存储区,因此当前运行函数的数据区必在栈顶。

堆栈特点:LIFO,除非转移或中断,堆栈内容的存或取表现出线性表列的性质。

正是如此,程序不要求跟踪当前进入堆栈的真实单元,而只要用一个具有自动递增或自动递减功能的堆栈计数器,便可正确指出最后一次信息在堆栈中存放的地址。

一个递归函数的运行过程类型于多个函数的嵌套调用,只是调用函数和被调用函数是同一个函数。

因此,和每次调用相关的一个重要的概念是递归函数运行的“层次”。

假设调用该递归函数的主函数为第0层,则从主函数调用递归函数为进入第1层;从第i层递归调用本函数为进入下一层,即i+1层。

反之,退出第i层递归应返回至上一层,即i-1层。

为了保证递归函数正确执行,系统需设立一个“递归工作栈”,作为整个递归函数运行期间使用的数据存储区。

每一层递归所需信息构成一个“工作记录”,其中包括所有实参、所有局部变量以及上一层的返回地址。

每进入一层递归,就产生一个新的工作记录压入栈顶。

每退出一层递归,就从栈顶弹出一个工作记录,则当前执行层的工作记录必是递归工作栈栈顶的工作记录,称这个记录为“活动记录”,并称指示活动记录的栈顶指针为“当前环境指针”。

????下面为图例,以三个盘子为例:??Hanoi塔问题中函数调用时系统所做工作处参考文章:《递归处理汉诺塔问题》。

相关文档
最新文档