汉诺塔问题的程序实现(hanoi塔)

合集下载

python汉诺塔算法讲析

python汉诺塔算法讲析

python汉诺塔算法讲析汉诺塔(Tower of Hanoi)是一个经典的递归问题,算法的目标是将一堆盘子从一个柱子移动到另一个柱子,每次只能移动一个盘子,并且不能将较大的盘子放在较小的盘子上面。

算法的基本思想是将问题分解为三个子问题:将n-1个盘子从起始柱子移动到中间柱子,将最大的盘子从起始柱子移动到目标柱子,最后将n-1个盘子从中间柱子移动到目标柱子。

这样的分解可以通过递归实现。

下面是一个用Python实现汉诺塔算法的示例代码:```pythondef hanoi(n, source, target, auxiliary):if n > 0:# 将n-1个盘子从起始柱子移动到中间柱子hanoi(n-1, source, auxiliary, target)# 将最大的盘子从起始柱子移动到目标柱子print(f"Move disk {n} from {source} to {target}")# 将n-1个盘子从中间柱子移动到目标柱子hanoi(n-1, auxiliary, target, source)# 测试代码hanoi(3, 'A', 'C', 'B')```在这个示例代码中,hanoi函数接受四个参数:n表示盘子的数量,source表示起始柱子,target表示目标柱子,auxiliary表示中间柱子。

在函数的实现中,首先判断n是否大于0,如果是,则递归地调用hanoi函数来移动n-1个盘子。

然后,打印出将最大的盘子从起始柱子移动到目标柱子的操作。

最后,再次递归地调用hanoi函数来移动剩余的n-1个盘子。

在测试代码中,我们使用3个盘子从柱子A移动到柱子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语言例题10-5 汉诺(hanoi)塔问题

c语言例题10-5 汉诺(hanoi)塔问题

汉诺塔问题是一个经典的递归问题。

在汉诺塔问题中,有三根柱子,第一根柱子上从下到上放着n 个盘子,目标是将这些盘子从第一根柱子移动到第三根柱子上,并且只能每次移动一个盘子,并且不能将一个较大的盘子放在较小的盘子上面。

以下是一个使用 C 语言实现的汉诺塔问题的示例代码:```c#include <stdio.h>void hanoi(int n, char A, char B, char C) {if (n == 1) {printf("Move disk 1 from %c to %c\n", A, C);return;}hanoi(n - 1, A, C, B);printf("Move disk %d from %c to %c\n", n, A, C);hanoi(n - 1, B, A, C);}int main() {int n = 3; // 盘子数量hanoi(n, 'A', 'B', 'C'); // 调用递归函数,将盘子从A 柱子移动到 C 柱子,B 柱子作为辅助柱子return 0;}```在这个代码中,我们定义了一个`hanoi` 函数来递归地解决汉诺塔问题。

在`hanoi` 函数中,我们首先检查盘子数量是否为1,如果是,则直接将盘子从起始柱子移动到目标柱子。

否则,我们使用两个辅助柱子来将n-1 个盘子从起始柱子移动到第二个辅助柱子上,然后将最后一个盘子从起始柱子移动到目标柱子上,最后再将n-1 个盘子从第二个辅助柱子移动到目标柱子上。

在`main` 函数中,我们定义了盘子数量n,并调用了`hanoi` 函数来解决问题。

【C语言程序设计】汉诺塔问题,用C语言实现汉诺塔!

【C语言程序设计】汉诺塔问题,用C语言实现汉诺塔!

【C语⾔程序设计】汉诺塔问题,⽤C语⾔实现汉诺塔!汉诺塔问题是指:⼀块板上有三根针 A、B、C。

A 针上套有 64 个⼤⼩不等的圆盘,按照⼤的在下、⼩的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动⼀个圆盘,移动过程可以借助 B 针。

但在任何时候,任何针上的圆盘都必须保持⼤盘在下,⼩盘在上。

从键盘输⼊需移动的圆盘个数,给出移动的过程。

算法思想对于汉诺塔问题,当只移动⼀个圆盘时,直接将圆盘从 A 针移动到 C 针。

若移动的圆盘为 n(n>1),则分成⼏步⾛:把 (n-1) 个圆盘从 A 针移动到 B 针(借助 C 针);A 针上的最后⼀个圆盘移动到 C 针;B 针上的 (n-1) 个圆盘移动到 C 针(借助 A 针)。

每做⼀遍,移动的圆盘少⼀个,逐次递减,最后当 n 为 1 时,完成整个移动过程。

因此,解决汉诺塔问题可设计⼀个递归函数,利⽤递归实现圆盘的整个移动过程,问题的解决过程是对实际操作的模拟。

程序代码#include <stdio.h>int main(){int hanoi(int,char,char,char);int n,counter;printf("Input the number of diskes:");scanf("%d",&n);printf("\n");counter=hanoi(n,'A','B','C');return0;}int hanoi(int n,char x,char y,char z){int move(char,int,char);if(n==1)move(x,1,z);else{hanoi(n-1,x,z,y);move(x,n,z);hanoi(n-1,y,x,z);}return0;}int move(char getone,int n,char putone){static int k=1;printf("%2d:%3d # %c---%c\n",k,n,getone,putone);if(k++%3==0)printf("\n");return0;}调试运⾏结果:当移动圆盘个数为 3 时,具体移动步骤如下所⽰:Input the number of diskes:31: 1 # A---C2: 2 # A---B3: 1 # C---B4: 3 # A---C5: 1 # B---A6: 2 # B---C7: 1 # A---C总结:本实例中定义的 hanoi() 函数是⼀个递归函数,它有四个形参"n""x""y""z"。

scratch汉诺塔递归算法

scratch汉诺塔递归算法

Scratch汉诺塔递归算法1. 引言汉诺塔(Hanoi Tower)是一种经典的数学问题,它可以帮助我们理解递归算法的原理和应用。

在这个任务中,我们将使用Scratch编程语言来实现汉诺塔递归算法。

2. 汉诺塔问题简介汉诺塔问题源于印度传说中的一个故事。

据说,在一个庙里有三根针,第一根针上套着64个不同大小的金盘子,大的在下面,小的在上面。

庙里的和尚每天都要将这些金盘子从第一根针移动到第三根针上,但是移动时必须遵守以下规则:1.每次只能移动一个盘子;2.每次移动必须将较小的盘子放在较大的盘子上面;3.可以借助第二根针作为中转。

3. 算法设计思路要解决汉诺塔问题,我们可以使用递归算法。

递归是一种函数调用自身的方法。

对于汉诺塔问题来说,我们可以将其分解为三个步骤:1.将n-1个盘子从第一根针移动到第二根针(借助第三根针作为中转);2.将第n个盘子从第一根针移动到第三根针;3.将n-1个盘子从第二根针移动到第三根针(借助第一根针作为中转)。

这样,我们可以通过递归调用这三个步骤来解决汉诺塔问题。

4. Scratch实现在Scratch中实现汉诺塔递归算法,我们需要创建以下角色和代码块:4.1 角色设计我们需要创建三个角色来表示三根针,以及一个角色来表示金盘子。

每个角色都应该有一个变量来表示当前所在的位置。

4.2 代码块设计我们需要设计以下代码块来实现汉诺塔递归算法:4.2.1 初始化代码块在初始化时,我们需要将金盘子放置在第一根针上,并设置好每个金盘子的大小。

当绿旗被点击时把金盘子放置在第一根针上设置金盘子大小4.2.2 移动代码块移动一个金盘子的过程可以分为以下几步:1.判断当前金盘子是否在目标针上;2.如果在目标针上,结束移动;3.如果不在目标针上,找到下一个需要移动到的位置(借助另外一根针);4.将当前金盘子移动到下一个位置;5.递归调用移动代码块,将剩余的金盘子移动到目标针上。

当收到 [移动金盘子 v] 消息时如果 [当前位置 v] = [目标位置 v] ?那么结束此脚本否则设置 [下一个位置 v] 为 (3 - [当前位置 v] - [目标位置 v])把金盘子放置在第 [下一个位置 v] 根针上把金盘子移到第 [目标位置 v] 根针上发送消息 (移动金盘子) 给自己并等待 (0.5) 秒4.2.3 触发移动代码块为了触发整个移动过程,我们可以创建一个按钮,并在其点击事件中调用移动代码块。

汉诺塔递归算法及详解

汉诺塔递归算法及详解

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

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

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

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

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

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

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

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

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

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

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

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

汉诺塔问题的程序实现

汉诺塔问题的程序实现

汉诺塔问题的程序实现汉诺塔问题的程序实现实验⽬的:运⽤程序解决汉诺塔(hanoi)问题。

汉诺塔问题:假设有3个分别命名为A,B,C的塔座,在塔座A上插有n个直径⼤⼩各不相同,依⼩到⼤编号为1,2....,n的圆盘。

现要求将A轴上的n个圆盘移到C并仍按同样顺序叠排,圆盘按以下规则(1)每次只能⼀动⼀个盘⼦(2)圆盘可以插在A,B,C中任⼀个塔座上(3)任何时刻都不能将⼀个较⼤的圆盘压在较⼩的圆盘之上。

A B C实验分析:汉诺塔问题可以规划为⼀个递归的问题予以分析,将n个盘⼦从A针移动到C 针可进⾏3个步骤:(1)将A上n-1的个盘⼦移到B针上;(2)把A针最后1个盘⼦移到C针上;(3)再把B盘⼦上的n-1个移到C针上。

实验过程:#includeusing namespace std;void main(){void hanoi(int m,char A,char B,char C); //A代表初始柱⼦,B代表辅助柱⼦,C代表⽬标柱⼦int m;printf("请输⼊盘⼦的个数:");scanf("%d", &m);printf("当盘⼦的个数为%d时移动的步骤是:\n",m);hanoi(m,'A','B','C');}void hanoi(int n,char X,char Y,char Z){void move(char X,char Z );if(n==1)move(X,Z);else{hanoi(n-1,X,Z,Y);move(X,Z);hanoi(n-1,Y,X,Z);}}void move(char x,char y){printf("%c-->%c\n",x,y);}过程:A代表初始柱⼦,B代表辅助柱⼦,C代表⽬标柱⼦。

⽽a代表第⼀根柱⼦,b代表第⼆根柱⼦,c代表第三根柱⼦。

汉诺塔python代码

汉诺塔python代码

汉诺塔python代码汉诺塔游戏是一种经典的益智游戏,它的规则非常简单,但是解决这个问题却需要一定的思维能力,而且它还可以通过编程来实现。

Python是一门非常流行的编程语言,因此在这里我们将介绍如何使用Python来实现汉诺塔游戏。

一、汉诺塔游戏的规则汉诺塔游戏有三个柱子和若干个盘子,每个盘子大小不同。

开始时,所有盘子都放在一个柱子上,按照从大到小的顺序排列。

目标是将所有盘子从起始柱子移动到目标柱子上,并保持原来的顺序不变。

在移动过程中必须遵守以下规则:1. 每次只能移动一个盘子;2. 盘子只能放在比它大的盘子上面;3. 不能将一个大盘子放在一个小盘子上面。

二、使用递归算法实现汉诺塔游戏递归算法是解决汉诺塔问题最常用的方法之一。

下面我们将介绍如何使用递归算法来实现汉诺塔游戏。

1. 定义函数首先我们需要定义一个函数来实现汉诺塔游戏。

在这个函数中,我们需要传入三个参数:起始柱子、目标柱子和盘子的数量。

def hanoi(start, target, n):2. 判断递归结束条件在递归过程中,我们需要判断递归结束的条件。

当n等于1时,表示只有一个盘子需要移动,此时我们可以直接将它从起始柱子移动到目标柱子上。

if n == 1:print(start, "->", target)3. 递归调用如果n大于1,则需要进行递归调用。

首先我们需要将n-1个盘子从起始柱子移动到辅助柱子上,然后再将最后一个盘子从起始柱子移动到目标柱子上,最后将n-1个盘子从辅助柱子移动到目标柱子上。

else:hanoi(start, other, n-1)print(start, "->", target)hanoi(other, target, n-1)4. 完整代码下面是完整的使用递归算法实现汉诺塔游戏的Python代码:def hanoi(start, target, n):if n == 1:print(start, "->", target)else:other = 6 - start - targethanoi(start, other, n-1)print(start, "->", target)hanoi(other, target, n-1)hanoi(1, 3, 3)三、使用非递归算法实现汉诺塔游戏除了递归算法,我们还可以使用非递归算法来实现汉诺塔游戏。

汉诺塔问题(Hanoi)的C++代码实现

汉诺塔问题(Hanoi)的C++代码实现

汉诺塔问题(Hanoi)的C++代码实现1 #include <iostream>2using namespace std;3//第⼀个塔为初始塔,第⼆个塔为中转塔,第三个塔为⽬标塔45int i = 1; //记录步数6void move(int n,char from,char to) //将编号为N的盘⼦由from塔转移到to塔7{8 cout<<"第"<<i++<<"步:将"<<n<<"号盘⼦"<<from<<"---->"<<to<<endl; //输出实例:第1步:将1号盘⼦A---->C9}1011void hanoi(int n,char from,char denpend_on,char to) //汉诺塔递归函数,参数依次为盘⼦数,起始塔,中转塔,⽬标塔12{13if(n==1)14 {15 move(1,from,to); //当需要移动的盘⼦数为1的时候,将此盘⼦从起始塔直接移动到⽬标塔16 }17else18 {19 hanoi(n-1,from,to,denpend_on); //当需要移动的盘⼦数不为1的时候,20//先将除最下⾯的盘⼦外的盘⼦从起始塔借助⽬标塔移动到中转塔21 move(n,from,to); //将剩下的最后的塔直接从起始塔移动到⽬标塔22 hanoi(n-1,denpend_on,from,to); //将之前移⾛的n-1个盘⼦从中转塔借助起始塔移动⾄⽬标塔23 }24}2526int main()27{28int n = 0;//n为盘⼦数29 cout<<"请输⼊盘⼦的个数:";30 cin>>n;31while(n<=0)//⾮法盘⼦数判断32 {33 cout<<"盘⼦的个数不应⼩于1,请重新输⼊:";34 cin>>n;35 }36if(n>0)37 {38char x='A',y='B',z='C';39 cout<<"盘⼦移动情况如下:"<<endl;40 hanoi(n,x,y,z); //调⽤hanoi函数41return0;42 }43 }运⾏结果:递归实现,未对过程进⾏存储。

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

问题重述:有三根柱A、B、C,在柱A上有N块盘片,所有盘片都是大的在下面,小片能放在大片上面。

现要将A上的N块盘片移到C柱上,每次只能移动一片,而且在同一根柱子上必须保持上面的盘片比下面的盘片小,输入任意的N,输出移动方法。

(注意:这是一个古老的传说,传说是如果把64个盘子由A柱移到了C柱的话,那么世界末日就到了,事实上如果要把64个盘子从A柱移到C柱的话,即使用计算机运算,也要计算数亿年,所以这个预言未必不是真实。

)【分析】我们可以这样考虑,当n=1时,我们只要直接将A柱的盘子移到C柱,当n>1时,我们可以先把n-1个盘子由A柱通过C柱移到B柱,此时就可以把A柱剩下的最后一个盘子直接移到C柱,这样接下来只要把n-1个盘子通过A柱移到C 柱即可,如果就构成了递归的思路,我们可以定义个移动过程mov(n,a,b,c)表示将n个盘子从a通过b移到c1.只要求输出搬运的次数#include <iostream>using namespace std;int m=0;void move(){m++;}void I(int n){if(n==1)move();else{I(n-1);move();I(n-1);}}int main(){I(3);cout<<m<<endl;cout<<"输出完毕!"<<endl;return 0;}更加简单的方法!#include <iostream>using namespace std;int fact(int n){if(n==1)return(1);elsereturn((2*fact(n-1)+1));}int main(){cout<<fact(3)<<endl;}2.不仅要求输出搬运的次数,而且要输出每个步骤的详细搬运#include <iostream>using namespace std;int m=0;void Move(int n,char x,char y){cout<<"把"<<n<<"号从"<<x<<"挪动到"<<y<<endl;m++;}void Hannoi(int n,char a,char b,char c){if(n==1)Move(1,a,c);else{Hannoi(n-1,a,c,b);Move(n,a,c);Hannoi(n-1,b,a,c);}}int main(){int i;cout<<"请输入圆盘数"<<endl;cin>>i;Hannoi(3,'a','b','c');cout<<"总的搬运次数"<<m<<endl;cout<<"输出完毕!"<<endl;return 0;}}另外一种不利用递归的解法(很抱歉,我自己也没调出来,实在太复杂了)#include <iostream>using namespace std;//圆盘的个数最多为64const int MAX = 1;//用来表示每根柱子的信息struct st{int s[MAX]; //柱子上的圆盘存储情况int top; //栈顶,用来最上面的圆盘char name; //柱子的名字,可以是A,B,C 中的一个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//入栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输入圆盘的个数st ta[3]; //三根柱子的信息用结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从大到小的顺序放在柱子A 上for (int i=0; i<n; i++)ta[0].s[i] = n - i;//柱子B,C 上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int j=0; j<n; j++)ta[1].s[j] = ta[2].s[j] = 0;//若n 为偶数,按顺时针方向依次摆放A B Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else //若n 为奇数,按顺时针方向依次摆放A C B{ta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; i<y; i++)sum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针方向把圆盘1 从现在的柱子移动到下一根柱子ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上if (k < max){ //把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i+1)%3].name<< " to " << ta[(i-1)%3].name << endl;}}}}补充知识:【典型例题1】求阶乘n!#include <iostream>using namespace std;int fact(int n){if(n==0)return(1);elsereturn(n*fact(n-1)); }int main(){cout<<fact(3)<<endl; }。

相关文档
最新文档