导航:首页 > 源码编译 > 汉诺塔递归算法分析

汉诺塔递归算法分析

发布时间:2023-05-03 13:18:41

A. 什么是递归算法

递归算法就是一个函数通过不断对自己的调用而求得最终结果的一种思维巧妙但是开销很大的算法。
比如:
汉诺塔的递归算法:
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');
}
我说下递归的理解方法
首先:对于递归这一类函数,你不要纠结于他是干什么的,只要知道他的一个模糊功能是什么就行,等于把他想象成一个能实现某项功能的黑盒子,而不去管它的内部操作先,好,我们来看下汉诺塔是怎么样解决的
首先按我上面说的把递归函数想象成某个功能的黑盒子,void hanoi(int n,char one,char two,char three); 这个递归函数的功能是:能将n个由小到大放置的小长方形从one 位置,经过two位置 移动到three位置。那么你的主程序要解决的问题是要将m个的"汉诺块"由A借助B移动到C,根据我们上面说的汉诺塔的功能,我相信傻子也知道在主函数中写道:hanoi(m,A,B,C)就能实现将m个块由A借助B码放到C,对吧?所以,mian函数里面有hanoi(m,'A','C','B');这个调用。
接下来我们看看要实现hannoi的这个功能,hannoi函数应该干些什么?
在hannoi函数里有这么三行
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
同样以黑盒子的思想看待他,要想把n个块由A经过B搬到C去,是不是可以分为上面三步呢?
这三部是:第一步将除了最后最长的那一块以外的n-1块由one位置经由three搬到two 也就是从A由C搬到B 然后把最下面最长那一块用move函数把他从A直接搬到C 完事后 第三步再次将刚刚的n-1块借助hannoi函数的功能从B由A搬回到C 这样的三步实习了n块由A经过B到C这样一个功能,同样你不用纠结于hanoi函数到底如何实现这个功能的,只要知道他有这么一个神奇的功能就行
最后:递归都有收尾的时候对吧,收尾就是当只有一块的时候汉诺塔怎么个玩法呢?很简单吧,直接把那一块有Amove到C我们就完成了,所以hanoni这个函数最后还要加上 if(n==1)move(one,three);(当只有一块时,直接有Amove到C位置就行)这么一个条件就能实现hanoin函数n>=1时将n个块由A经由B搬到C的完整功能了。
递归这个复杂的思想就是这样简单解决的,呵呵 不知道你看懂没?纯手打,希望能帮你理解递归
总结起来就是不要管递归的具体实现细节步骤,只要知道他的功能是什么,然后利用他自己的功能通过调用他自己去解决自己的功能(好绕口啊,日)最后加上一个极限情况的条件即可,比如上面说的1个的情况。

B. 汉诺塔递归算法是什么

如下:

1、汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。

大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

2、抽象为数学问题:从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数。

算法分析(递归算法):

实现这个算法可以简单分为三个步骤:把n-1个盘子由A 移到 B;把第n个盘子由 A移到 C;把n-1个盘子由B 移到 C。从这里入手,在加上上面数学问题解法的分析,我们不难发现,移到的步数必定为奇数步。

1、中间的一步是把最大的一个盘子由A移到C上去。

2、中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上。

3、中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上。

C. 汉诺塔递归问题

汉诺塔的递归算法与解析

从左到右 A B C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面.
如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号.

递归算法简单来说就是方法内部自己调用自己, 同时也一定有一个结束点. 如果对方法调用栈了解的话,其实是很容易理解方法的调用过程的, 就是从主线程开始调用方法进行不停的压栈和出栈操作. 方法的调入就是将方法压入栈中, 方法的结束就是方法出栈的过程, 这样保证了方法调用的顺序流. 如果跟踪递归的调用情况会发现也是如此, 到最后一定是这个方法最后从栈中弹出回到主线程, 并且结束.
栈的特点:先进后出。 比如一个方法 A 自己调用自己, 我用编号区分一下进栈过程:
A -> A(1) -> A(2) -> A(3)
在A(3)时满足某种条件得以退出, 回到 A(2), A(2)结束回到A(1), 再回到A, 出栈过程:
A(3) -> A(2) -> A(1) -> A
对于递归,还有一个形象的认识,就是我小时候家里有一个柜子, 柜子两端都是玻璃, 头伸进柜子看一面镜子,会看到镜子里还有镜子, 然后镜子里还有镜子, 但和递归的特点不同的是这镜子的反射是没有尽头的, 只要眼睛一直能看到底的话.
了解完递归春虚橡后, 再回头来看如何用递归的方式解决汉诺塔的问题.
案例 1 - 假设只有一个盘子的时候, 盘子数量 N=1
只有一个步骤 将第1个盘子从A移动到C, 为了对比方便我这样来描述这个步骤:
步骤 盘子编号 从柱子移动 移动到柱子
1 1 A C
案例 2 - 如果有两个盘子, 盘子数量 N = 2
步骤 盘子编号 从柱子移动 移动到柱子
1 1 A B
2 2 A C
3 1 B C
案例 3 - 如果有三个盘子, 盘子数量 N = 3
步骤 盘子编号 从柱子移动 移动到柱子
1 1 A C
2 2 A B
3 1 C B
4 3 A C
5 1 B A
6 2 B C
7 1 A C
如何找出盘子移动的规律 ?
我们要做的最重要的一件事情就是永远要把最底下的一个盘子从 A 移动到 C
看看上面从1个盘子的移动到3个盘子的移动, 在移动记录中,当盘子的编号和盘子数量相同的时候他们的步骤都是从A移动到C (看加粗的部分),其它的步骤对等.
再观察第3个案例中的第 1-3 步 和 第 5-7步
第 1-3 步 目的是从 A 移动扒旁到 B 如果我们把 B 当作终点, 那么这里的第 1-3 步理解起来和 第2个案例的三个步骤完全相同, 都是通过一个柱子来移誉祥动,和第2个案例比起来在后面加括号来表示
1 1 A C ( A -> B)
2 2 A B ( A -> C)
3 1 C B ( B -> C)
总结:将盘子B变成C即可.
第 5-7 步 目的是从 B 移动到 C 如果我们把 C 当作终点, 那么这里的 5-7 步理解起来和上面也是一样的, 和第2个案例的三个步骤也完全相同.和第2个案例比起来就是:
5 1 B A ( A -> B)
6 2 B C ( A- > C)
7 1 A C ( B -> C)
总结: 将盘子B变成A即可
根据这个演示可以明确几点规律:
1. 当盘子只有一个的时候,只有一个动作 从 A 移动到 C 即结束.
2. 当有N个盘子的时候, 中间的动作都是从 A 移动到 C, 那么表示最下面的第N个盘子移动完毕
3. 中间动作之上都可以认为是: 从 A 移动到 B
4. 中间动作之下都可以认为是: 从 B 移动到 C
2,3,4 可以表示为
1 1 A B
2 2 A C
3 1 B C
这种结构一直在重复进行,C#不太熟悉,试着写写,就有了以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataStructure
{
class HanoiTower
{

public void MoveDisk(int DiskQuantity,string PositionA, string PositionB, string PositionC)
{
// If there's only one disk, then end.
if (DiskQuantity == 1)
{
Console.WriteLine("Move disk from position {0} to {1}.", PositionA, PositionC);
// Must return
return;
}
else
{
// Step 1 - Change B to C (A --> B)
MoveDisk(DiskQuantity - 1, PositionA,PositionC,PositionB);
// Step 2 - No changes (A --> C)
MoveDisk(1, PositionA, PositionB, PositionC);
// Step 3 - Change B to A (A --> C)
MoveDisk(DiskQuantity - 1, PositionB, PositionA, PositionC);
}
}

static void Main(string[] args)
{
HanoiTower hanoi = new HanoiTower();

Console.WriteLine("Please input Disk Quantity:");
int DiskQuantity = Convert.ToInt32(Console.ReadLine());

hanoi.MoveDisk(DiskQuantity, "A", "B", "C");

Console.ReadKey();
}
}
}

结合上面的分析,最重要的就是这里的3步交换动作, 中间从 A到C的动作是最底层盘子的最终操作.
//Step 1 - Change B to C (A --> B)
MoveDisk(DiskQuantity - 1, PositionA,PositionC,PositionB);
//Step 2 - No changes (A --> C)
MoveDisk(1, PositionA, PositionB, PositionC);
//Step 3 - Change B to A (A --> C)
MoveDisk(DiskQuantity - 1, PositionB, PositionA, PositionC);
至于第1个参数为什么是DiskQuantity - 1,或者1 大家再回到上面看看是不是所有的步骤都是.. 1. 1,2,1. 1,2,1,3,1,2,1 这种以盘子数对称的结构,而它前后都是重复1,2,1 的过程.

D. 汉诺塔递归算法是什么

汉诺塔递归算法是算法分析。实现这个算法可以简单分为三个步骤:把n-1个盘子由A 移到 B;把第n个盘子由 A移到 C,把n-1个盘子由B 移到 C。

汉诺塔的来源及应用

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。

游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

汉诺塔问题是用递归方法求解的一个典型问题,在实际教学中,可以在传统教学方式的基础上,利用计算机辅助教学进行算法的模拟演示教学,使学生更容易接受和理解递归算法的思想,不但能提高学生的学习兴趣,而且还能取得较好的教学效果。

E. 汉诺塔递归算法是什么

汉诺塔是经典递归问题:

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。

游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

如果A只有一个(A->C)。

如果A有两个(A->B),(A->C),(B->C)。

如果A有三个(A->C),(A->B),(C->B),(A->C),(B->A),(B->C),(A->C)。

如果更多,那么将会爆炸式增长。

递归:就是函数自己调用自己。 子问题须与原始问题为同样的事,或者更为简单;递归通常可以简单的处理子问题,但是不一定是最好的。

其实递归在某些场景的效率是很低下的。尤其是斐波那契.从图你就可以发现一个简单的操作有多次重复。因为它的递归调用俩个自己。那么它的递归的膨胀率是指数级别的,重复了大量相同计算。

起源:

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。

大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

阅读全文

与汉诺塔递归算法分析相关的资料

热点内容
车载云服务器记录 浏览:738
四川金星压缩机制造有限公司 浏览:53
移动平台图片压缩算法 浏览:35
银行项目java 浏览:568
怎样将pdf转换为ppt 浏览:595
纯净服务器怎么开服 浏览:286
比泽尔压缩机如何换油 浏览:818
编译链接如何生成exe 浏览:73
jre编译运行环境 浏览:271
怎么解压镜像系统 浏览:190
程序员求助国企 浏览:838
云服务器网址租用多少钱 浏览:942
行车记录仪安卓版怎么用 浏览:500
java是不是数字 浏览:183
php模拟浏览器环境 浏览:353
编程谁都能学会吗 浏览:407
使用国家反诈app都要开启什么 浏览:712
下载民宿APP有什么用 浏览:52
续子语pdf 浏览:385
2021年加密货币最新行情 浏览:162