Hanoi塔问题(C语言程序)
实验二 HANOI塔问题
实验二递归程序设计一、实验目的1、理解PROLOG编制递归程序的方法:边界条件与递归部分的设计;2、熟悉运用递归分析、解决问题的方法。
二、实验内容及步骤(一)Hanoi塔问题:如上图,目的是把左边的所有盘子移到右边的杆子上。
一次只能移动一个盘子,可以使用中间的杆子作为临时存放盘子的地方。
在移动的过程中,小盘子必须放在大盘子之上。
分析:用递归来解决这个问题。
如果只有一个盘子,直接移过去就行了,这是递归的边界条件。
如果要移动N个盘子,就要分三步走:1、把N-1个盘子移动到中间的杆子上(把右边的杆子作为临时存放盘子的位置)2、把最后一个盘子直接移到右边的杆子上。
3、最后把中间杆子上的盘子移到右边的杆子上(把左边的杆子作为临时存放盘子的位置)。
上面第一、三步用到了递归。
我们看到,通过递归把N个盘子的问题变成了两个N-1个盘子的问题。
如此下去,最后就变成了2个一个盘子的问题了,这也就是说问题被解决了。
1)Hanoi塔的Prolog代码:hanoi(N):-move(N,left,middle,right).move(1,A,_,C):-inform(A,C),!.{!为cut操作,截断进一步搜索}move(N,A,B,C):-N1is N-1,move(N1,A,C,B),inform(A,C),move(N1,B,A,C).inform(Loc1,Loc2):-nl,write(“Move a disk from”Loc1“to”Loc2).?-hanoi(3).主程序为hanoi,它的参数为盘子的数目。
它调用递归谓词move来完成任务。
三个杆子的名字分别为left、middle、right。
第一个move子句是边界情况,即只有一个盘子时,直接调用inform显示移动盘子的方法。
后面使用cut,是因为:如果只有一个盘子,就是边界条件,无需再对第二条子句进行匹配了。
第二个move子句为递归调用,首先把盘子数目减少一个,再递归调用move,把N-1个盘子从A杆通过C杆移到B杆,再把A杆上的最后一个盘子直接从A杆移到C杆上,最后再递归调用move,把B杆上的N-1个盘子通过A杆移到C杆上。
c汉诺塔问题递归算法
c汉诺塔问题递归算法
汉诺塔问题是一个经典的递归问题,它可以通过递归算法来求解。
下面是汉诺塔问题的递归算法:
cCopycodevoidhanoi(intn,charA,charB,charC){//将n个盘子从A 经由B移动到
Cif(n==1){printf("Movedisk1from%cto%c\n",A,C);}else{hanoi(n -1,A,C,B);//将n-1个盘子从A经由C移动到
Bprintf("Movedisk%dfrom%cto%c\n",n,A,C);hanoi(n-1,B,A,C);//将n-1个盘子从B经由A移动到C}}上述算法中,hanoi函数接受四个参数,其中n表示盘子的数量,A、B、C分别表示三根柱子,其中A是起始柱子,B是中间柱子,C是目标柱子。
如果n=1,则直接将第一个盘子从A移动到C。
如果n1,则将n个盘子从A经由C移动到B,然后将第n个盘子从A移动到C,最后将n个盘子从B经由A移动到C。
这样递归调用,直到n=1的时候,递归结束。
c语言 递归函数实现 汉诺塔
c语言递归函数实现汉诺塔
汉诺塔是一种著名的数学问题,也是经典的递归算法题目。
它包含三个塔座和一些圆盘,盘子大小不一,大的在下面,小的在上面。
开始时,所有的盘子都放在第一个塔座上,要把它们从第一个塔座移动到第三个塔座上,移动时要遵循以下规则:
1.每次只能移动一个盘子;
2.大盘子不能放在小盘子上面。
递归算法是实现汉诺塔问题的最简单方法。
在递归函数中,把整个问题分解成子问题,直至问题规模为1时,直接解决。
下面是C语言实现汉诺塔问题的递归函数:
void hanoi(int n, char A, char B, char C) {
if (n == 1) {
printf('%c -> %c
', A, C);
return;
}
hanoi(n-1, A, C, B);
printf('%c -> %c
', A, C);
hanoi(n-1, B, A, C);
}
函数参数说明:
n:当前塔座上的盘子数量;
A, B, C:三个塔座的名称。
函数实现说明:
1.当塔座上只有一个盘子时,直接将其从A塔座移动到C塔座上;
2.当塔座上有n个盘子时,首先将A塔座上的n-1个盘子移动到B塔座上,然后将A塔座上的一个盘子移动到C塔座上,最后将B塔座上的n-1个盘子移动到C塔座上。
通过递归调用hanoi函数,就能够解决汉诺塔问题。
Hanoi塔的问题
Hanoi塔的问题/*Hanoi塔的问题题目描述:Hanoi塔的问题相信大家很熟悉了:有三根针上放了一些圆盘,半径各不相同,大的不能放在小的上面,每次只能移动一个,要把它们全部移到第三根针上输入:多组测试数据,每组两行。
第一行是n(1<=n<=32),表示有多少个盘接下来一行由n个数字1,2,3组成的数字串,第一个数表示最大的盘在第几根针上,第二个数表示次大的盘在第几根针上,第n个数表示最小的盘在第几根针上,输入的n为0的时候结束输出:全部移动到第三根针上所需要的最少步数样例输入:31113321*/#include <stdio.h>long i64Hanoi[33]; // 表示把i 个盘从一根柱子移动到另一根柱子所需的最少步数为i64Hanoi[i]int iDisk[33]; // 表示i 号盘在iDisk[i] 号柱上/****************************函数功能:计算把iCount 个盘移动到iAim 号柱的最少步数入口参数:盘子个数:int iCount目标柱号码:int iAim返回值:把iCount 个盘移动到iAim 号柱的最少步数*****************************/long Hanoi(int iCount, int iAim) // 计算把iCount 个盘移动到iAim 号柱的最少步数{if (iCount==0) // 递归边界:当0个盘子,最少步数也为0return 0;else if (iDisk[iCount-1]==iAim) // 当大盘在目标柱,只需移动余下(n-1)个盘到目标柱return Hanoi(iCount-1, iAim);else// 大盘不在目标柱的时候应该做下面3步:// 1)把除大盘以外的(n-1)个盘移动到另一根非目标柱:Hanoi(iCount-1, 6-iAim-iDisk[iCount-1]) (return 的第一部分)// 其中:6-iAim-iDisk[iCount-1] 恰为另一根非目标柱的号码。
数据结构C语言实现之hanoi塔问题
y
move(Sx, n, Sz);
//将编号为 n 的圆盘从 x 移到 z
Hanoi(n-1, Sy, Sx, Sz); //将 y 上编号为 1 至 n-1 的圆盘利用 x 移到z} Nhomakorabea}
void main() {
SNode *Sx, *Sy, *Sz; int i = 0, n = 0; char ck = 0;
//将 x 上的圆盘编号
i++;
}
Hanoi(n, &Sx, &Sy, &Sz);
printf("\n 从 X 移到 Z 的结果是:\n");
Print(&Sz);
}
m = Pop(S1); Push(S2, m); }
void Hanoi(int n, SNode **Sx, SNode **Sy, SNode **Sz)
{
if (n == 1)
move(Sx, 1 , Sz);
//将编号为 1 的圆盘由 x 移到 z
else
{
Hanoi(n-1, Sx, Sz, Sy); //将 x 上编号为 1 到 n-1 的圆盘利用 z 移到
int data; struct Stack *next; }SNode;
void InitStack(SNode **S) {
*S = (SNode *) malloc (sizeof(SNode)); (*S)->next = NULL; //先建立一个带头结点 }
void Push(SNode **S, int ck)
void Print(SNode **S) {
SNode *p; p = (*S)->next; while(p) {
汉诺塔(C语言)
bar(160, 540, 240, 580);
setfont(30, 0, "黑体");
++s[0].top;//进栈
for (int i1 = 0; i1 < 4; i1++)
{
p[i]->a[i1] = ta[i1];
s[0].stack[s[0].top] = p[i];//记录每个矩形的位置,top为圆盘的个数
}
}
Hannoi(n, 'a', 'b', 'c');//汉诺塔递归函数
//绘制运动画面的的环境
setcolor(RED);
//三根红色线段作为钢针
line(400, 110, 400, 500);
line(600, 110, 600, 500);
line(200, 110, 200, 500);
//长方体形的底座
setfillstyle(LIGHTGRAY);
bar3d(80, 500, 720, 510, 10, true);
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#define MAX 64//圆盘的最大数目
#define NULL 0
//定义栈
struct STKNODE
{
int a[4];
};
struct STK
{
STKNODE*stack[MAX];
inttop;
};
//定义全局变量
STK s[3];//声明三个栈,分别代表一号二号三号钢针上圆盘的状态
c语言递归汉诺塔每一步详解
递归汉诺塔是一个经典的递归问题,它要求将一堆圆盘从一根柱子移动到另一根柱子上,且规定不能通过其他圆盘。
这个问题可以通过递归算法来解决。
在每一步中,我们可以选择将当前最大的圆盘从起始柱子移动到目标柱子,或者将两个较小的圆盘移动到另一个柱子上。
递归函数需要考虑三个柱子的状态:起始柱子、目标柱子和柱子。
在函数中,我们需要判断当前情况是否可以进行移动,如果可以,则执行相应的移动操作,否则返回上一个递归函数继续执行。
最终,当所有圆盘都移到目标柱子上时,问题得到解决。
汉诺塔问题c语言实现
汉诺塔问题c语言实现
汉诺塔问题是一道经典的递归问题,它涉及到将若干个不同大小的圆盘,按照一定规则移动到另一个柱子上的问题。
这个问题可以用C语言进行实现。
首先,我们需要定义汉诺塔问题的三个柱子,并初始化三个柱子上的圆盘。
然后,我们可以编写一个递归函数,用来移动圆盘。
该函数的参数包括当前所在的柱子、目标柱子以及要移动的圆盘数量。
在函数内部,我们可以先将除要移动的圆盘外的其余圆盘,从当前柱子移动到中间柱子上。
然后,将要移动的圆盘从当前柱子移动到目标柱子上。
最后,将中间柱子上的其余圆盘,从中间柱子移动到目标柱子上。
递归的结束条件是只要有一个圆盘需要移动,就直接将其从当前柱子移动到目标柱子上即可。
- 1 -。
c语言 递归函数实现 汉诺塔
c语言递归函数实现汉诺塔汉诺塔,也叫河内塔,是国际上广为流传的智力游戏,大约在1200年前就有了。
一座铜塔,塔内共有三个座,最左侧座上有64个从小到大依次排列的盘子,如何把这些盘子全部移到最右侧的底座,移动过程中,需要满足以下三个条件:一次只能移动一个盘子,任何时刻大盘子都必须在小盘子上方,且不能从底座间途中取出已经放好的盘子。
而递归函数则是实现这一问题常用的一种方法。
一、分析问题将n个盘子从A柱移动到C柱,可以分成三个步骤:1、把A柱上的n-1个盘子移动到B柱上;2、把A柱上最后一个盘子(即最大的盘子)移动到C柱上;3、把B柱上的n-1个盘子移动到C柱上。
如此递归下去,直到只有一个盘子需要移动的时候,就可以进行移动了。
二、实现递归函数根据上述分析,可以写出递归函数如下:void hanoi(int n, char A, char B, char C){if(n == 1){printf("Move disk %d from %c to %c \n", n , A, C);}else{hanoi(n-1, A, C, B); //把A柱上的n-1个盘子移动到B柱上printf("Move disk %d from %c to %c \n", n , A, C); //把A 柱上的最大盘子移到C柱上hanoi(n-1, B, A, C); //把B柱上的n-1个盘子移动到C柱上}}三、调用递归函数在主函数中调用递归函数,可以输入盘子的个数n和底部柱的名称A、B、C,并执行hanoi函数:int main(){int n;printf("Please enter the number of disks: ");scanf("%d", &n);hanoi(n, 'A', 'B', 'C');return 0;}四、运行结果当输入盘子的个数为3时,运行结果如下:Please enter the number of disks: 3Move 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五、总结通过递归函数实现汉诺塔问题,可以更好地理解递归的概念和实现方式。
hanoi塔问题
(0,B,A,C) 1: B->A (0,C,B,A) ⑤
�
源轴
辅助轴
目的轴
n (1 ~ n)
n-1(1~n-1)
A A A B
B C
C B C
1(n)
n-1(1~n-1)
A
C
C语言程序设计
Hanio塔问题
hanoi( n, one , two , three )
1: … 2: 输入n=3, if ( n==1 ) 将one轴上的圆盘移到three轴; 1: 输出结果为 : else 3: { hanio( n-1, one, three, two ) ; 1: 将第 n 号圆盘由 one 轴移动到 three 轴 ; 2: hanio( n-1, two, one, three ) ; 1: } …
执行程序,
4.设计程序:
A --> C A --> B C --> B A --> C B --> A B --> C A --> C
void hanoi(int n, char one, char two, char three) { if ( i==1) printf("%d: %c-->%c\n", n, one, three); else void main() { hanoi( n-1, one, three, two ) ; {int m ; printf("%d: %c-->%c\n", n, one, three); scanf("%d", &m) ; hanoi(n-1, two, one, three ) ; } hanoi(m, 'A', 'B', 'C' ); } }
汉诺塔问题c语言实现
汉诺塔问题c语言实现汉诺塔是一个经典的递归问题,也是算法学习中的重要内容。
它可以帮助我们熟悉递归的思想和实现。
在这篇文章中,我将用C语言实现汉诺塔问题,并分步骤介绍实现过程。
1. 首先,我们需要了解汉诺塔问题的规则。
问题的规则如下:a. 有三个柱子A、B、C,A柱子有n个盘子,盘子大小不一,大盘子在下,小盘子在上;b. 要求将所有盘子从A柱子移动到C柱子,可以使用B柱子作为辅助;c. 在移动过程中,大盘子不能放在小盘子上面。
2. 接下来,我们定义一个函数hanoi()来实现汉诺塔问题的递归调用。
函数的参数如下:a. 一个整数n,表示A柱子上的盘子数;b. 一个字符变量ori,表示原始柱子的位置;c. 一个字符变量buf,表示缓冲柱子的位置;d. 一个字符变量dst,表示目标柱子的位置。
函数hanoi()的具体实现如下:```void hanoi(int n, char ori, char buf, char dst){if(n == 1){printf("将第%d个盘子从%c移动到%c\n", n, ori, dst);}else{hanoi(n-1, ori, dst, buf);printf("将第%d个盘子从%c移动到%c\n", n, ori, dst);hanoi(n-1, buf, ori, dst);}}```上述代码中,if语句判断是否只有一个盘子,如果是则直接移动到目标柱子上。
else语句则使用递归的方式将除目标柱子的盘子移动到缓冲柱子上,再将目标柱子的盘子移动到目标柱子上,最后将缓冲柱子的盘子移动到目标柱子上。
3. 接下来,我们在主函数中调用hanoi()函数,并将A柱子上的盘子数作为参数传入该函数。
同时,我们需要输入A柱子的位置、缓冲柱子的位置和目标柱子的位置。
具体实现如下:```int main(){int n;char ori, buf, dst;printf("请输入A柱子上的盘子数:");scanf("%d", &n);printf("请输入A柱子的位置(如:A、B、C):");scanf("%*c%c", &ori);printf("请输入缓冲柱子的位置(如:A、B、C):");scanf("%*c%c", &buf);printf("请输入目标柱子的位置(如:A、B、C):");scanf("%*c%c", &dst);hanoi(n, ori, buf, dst);return 0;}```4. 运行程序后,输入一个正整数n和三个柱子的位置,程序会按照汉诺塔问题的规则,输出移动的步数和每一步的过程。
汉诺塔问题C语言程序设计
三峡大学理学院2011级电信专业《高级语言程序设计》课程设计说明书设计题目: 汉诺塔的搬移过程设计班级:高级语言程序设计1 班学号:2011142227姓名:徐飞完成日期:2012 年6月20日1设计任务设计题目:用递归法计算解决汉诺塔问题,并能够演示解决汉诺塔问题过;要求:设计一个运用递归法计算解决汉诺塔问题C语言程序;2 汉诺(Hanoi)塔问题的提出古代有一个梵塔,塔内有A,B,C,3个座,座A上有64个大小不等的盘子,大的在下,小的在上(如下图)。
有一个和尚想把这64个盘子从座A全部移到座C ,在移动过程中可以借用座A,座B或座C,但每次只允许移动一个盘子,并且不允许大盘放在小盘的上面。
3编程思路首先,要找出递归的两个关键点,即:递归终止条件:只有一个盘子时,可以移动。
递归表达式:要找出递归表达式,可以如下设想:下面以3个盘子为例说明详细的移动过程:(1)将座A上的2个盘子移动到座B上;(2)将座A上的1个盘子移动到座C上;(3)将座B上的2个盘子移动到座C上;上面第1步可用递归方法分解为:(1)将座A上的1个盘子从座A移动到座C上;(2)将座A上的1个盘子从座A移动到座B上;(3)将座C上的1个盘子从座C移动到座B上;第(3)步可用递归方法分解为:(1)将座B上的1个盘子从座B移动到座A上;(2)将座B上的1个盘子从座B移动到座C上;(3)将座B上的1个盘子从座A移动到座C上;第(1)步操作可归纳为:将座A上的2个盘子借助座C移到座B; 第(3)步操作可归纳为:将座B上的2个盘子借助座A移到座C; 因此,将n个盘子从座A移到座C可以描述为:(1)将n-1个盘子从座A借助座C移到座B;(2)将剩下的一个盘子从座A移到座C;(3)将n-1个盘子从座B借助座A移到座C;3系统操作流程图;4.程序说明;函数HN(int n,char a,char b,char c)表示将n个盘子从座A移到座C,移动过程中借助B关键语句:HN(n-1,a,c,b);printf("from %c to %c\n",a,c);HN(n-1,b,a,c);假设盘子数为2、5,则其运行过程为:5源程序附录;#include<stdio.h> void main(){void HN(int n,char a,char b,char c); int m;printf("请输入盘子的个数:");scanf("%d",&m);printf("%d个盘子移动的步骤如下:\n",m);HN(m,'A','B','C');}void HN(int n,char a,char b,char c) {if(n==1)printf("from %c to %c\n",a,c);else{HN(n-1,a,c,b);printf("from %c to %c\n",a,c);HN(n-1,b,a,c);}}。
汉诺塔递归算法c++语言
汉诺塔递归算法c++语言一、算法概述汉诺塔问题是经典的递归问题,涉及到移动物体的操作和递归解决问题的策略。
通过使用C语言编写汉诺塔递归算法,我们可以更深入地理解递归思维和解决复杂问题的技巧。
二、算法描述汉诺塔问题的基本描述如下:有n个大小不一、重量不同、用不同材质制成的盘子,将它们从A柱移动到C柱,每次只能移动一个盘子,且每次移动的盘子必须放在比它小的柱子上。
汉诺塔递归算法的核心思想是将复杂问题分解为更小的子问题,直到达到基本情况(即无子问题需要解决),然后通过递归调用返回基本情况的结果,从而解决原始问题。
三、C语言实现以下是用C语言实现汉诺塔递归算法的代码:```c#include<stdio.h>voidhanoi(intn,charfrom,chartemp,charto){if(n==1){printf("Movedisk1from%cto%c\n",from,to);}else{//将n-1个盘子从from柱移动到temp柱,将最大的盘子从from柱移动到to柱hanoi(n-1,from,to,to);//递归调用,解决子问题//将最大的盘子从temp柱移动到to柱printf("Movedisk%dfrom%cto%c\n",n,from,to);//将n-1个盘子从to柱移动到temp柱,以便于将最大的盘子移动到to柱hanoi(n-1,temp,from,to);//递归调用,解决子问题){}}intmain(){intn=3;//盘子数量,可以根据需要修改hanoi(n,'A','B','C');//调用函数,将盘子从A柱移动到C柱return0;}```四、总结与思考通过使用C语言实现汉诺塔递归算法,我们可以更深入地理解递归思维和解决复杂问题的技巧。
在实际应用中,递归算法通常适用于那些可以分解为更小子问题的情况,通过逐个解决子问题,最终达到解决原始问题的目的。
汉诺塔c语言程序代码
汉诺塔c语言程序代码第一篇:汉诺塔c语言程序代码汉诺塔c语言程序代码(通过vc++6.0验证)(附讲解)让我们先看看代码吧 #include int hj(int a,int b, int c,int i){ int t;if(i==1) printf(“%d->%dn”,a,c);else {t=c;c=b;b=t;hj(a,b,c,i-1);printf(“%d->%dn”,a,b);t=a;a=c;c=t;t=b;b=c;c=t;hj(a,b,c,i-1);return 0;} } main(){ int a,b,c,i;a=1;b=2;c=3;printf(“请输入汉诺塔的盘数”);scanf(“%d”,&i);hj(a,b,c,i);return 0;}以上是汉诺塔的代码,该程序主要是运用了递归的思想,比如数学中的f(x)=f(x-1)+f(x-2),在本程序中为:int hj(int a,int b, int c,int i){ int t;if(i==1)printf(“%d->%dn”,a,c);else {t=c;c=b;b=t;hj(a,b,c,i-1);也就是说,我们在这个函数中再次调用这个函数,相当于一个循环,而在再次调用的过程中,i的值变成i-1,就类似于f(x-1),这样层层调用,最终就变成当i=1的时候的值,然后通过运算,计算出想要得到的值。
汉诺塔的数值分析:我们可以发现,当只有一个盘的时候,我们只需要做1->3(就是把第一个柱子上的最顶端的盘移动到第三根柱子,以下不再解释)当有两个盘的时候,是1->21->32->3 三个盘子是:1->31->23->21->32->12->3 分析一下可以得出以下结论:初始值a=1 b=2 c=3 一个盘子就是a->c 两个盘子与一个盘子的关系是:第一步:b与c交换值,然后打印a->c 第二步:打印a->b 第三步:a与c交换值,b与c交换值,打印a->c 进一步分析,便可以得出以下结论只要盘子数量为i(i大于1),那么它就有三部分第一部分,b与c交换值,然后运行i-1 第二部分,打印a->b 第三部分,a 与c交换值,b与c交换值,然后运行i-1 程序表示便是: if(i==1) printf(“%d->%dn”,a,c);else {t=c;c=b;(交换值)b=t;hj(a,b,c,i-1);printf(“%d->%dn”,a,b);t=a;a=c;c=t;(a c交换)t=b;b=c;c=t;(b c交换)hj(a,b,c,i-1);不明加QQ765233918(请写清备注)1->3第二篇:C语言程序设计(汉诺塔问题)C语言程序设计(汉诺塔设计)#include void main(){void tian(int n,int x,int y,int z);/*函数声明*/int m;printf(“please enter the number of diskes:n”);scanf(“%d”,&m);printf(“the step of move %d diskes :”,m);tian(m,'A','B','C');} void tian(int n,int x,int y,int z)/*当我选定这一行的时候然后单击组间选择调试run to_发现不管输入的x值是多少ABC的值都是65 66 67后来才发现原来是他们所代表的十进制的值*/ {void move(int x,int y);if(n==1)move(x,z);/*这里是递归函数的结束条件*/ else{tian(n-1,x,z,y);move(x,y);tian(n-1,y,x,z);} } void move(int x, int y)/*定义move函数用来显示移动的路线*/ {printf(“%c——>%cn”,x,y);} /*汉洛塔问题:如果有N个盘子那么可以简化为n-1个盘子和一个盘子来处理,只要先把上面的n-1个盘子从A——>B把第n个盘子由A——>C 再把n-1个盘子由B——>C 即可;n-1盘子那么可以简化为n-2个盘子和一个盘子来处理只要把上面的n-2个盘子从A——>B把第n个盘子由A——>C 再把n-1个盘子由B——>C 即可;n-3盘子那么可以简化为n-3个盘子和一个盘子来处理只要把上面的n-4个盘子从A——>B把第n个盘子由A——>C 再把n-1个盘子由B——>C 即可;N-4.....4个盘子那么可以简化为3个盘子和一个盘子来处理只要把上面的3个盘子有a 到b把第4个盘子由a到c 再把上面的三个盘子由b到c;3个盘子可以简化为。
c语言用递归算法实现汉诺塔
c语言用递归算法实现汉诺塔C语言是一种非常强大的编程语言,它提供了很多功能和工具来解决各种问题。
其中,递归是C语言中常用的一种算法,它在很多场景下都能发挥出强大的威力。
在本文中,我们将讨论如何使用递归算法来实现经典的数学问题——汉诺塔。
汉诺塔是由法国数学家Edouard Lucas在19世纪创建的一个谜题。
它包括三根柱子和一些盘子,盘子从小到大按顺序放置在柱子上。
游戏的目标是将所有盘子从起始柱子移动到目标柱子,期间可以使用中间柱子进行中转。
规则非常简单:一次只能移动一个盘子,并且大盘子不能放在小盘子上面。
为了解决汉诺塔问题,我们可以使用递归算法。
递归是指在定义过程或函数时使用自身的方法。
对于汉诺塔问题,我们可以将其分解为三个步骤:将n-1个盘子从起始柱子移动到中转柱子,将最大的盘子从起始柱子移动到目标柱子,最后将n-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);printf("The steps to solve the Hanoi T ower problem are:\n");hanoi(n, 'A', 'C', 'B');return 0;}在上面的代码中,我们定义了一个名为hanoi的递归函数,它具有四个参数:盘子的数量n,起始柱子from,目标柱子to,和中转柱子aux。
Hanoi(汉诺)塔问题
11:59
35
• 把上面3个步骤分成两类操作:
(1) 将n-1个盘从一个座移到另一个座上(n> 1)。这就是大和尚让小和尚做的工作,它 是一个递归的过程,即和尚将任务层层下放, 直到第64个和尚为止。 (2) 将1个盘子从一个座上移到另一座上。这是 大和尚自己做的工作。
11:59
36
• 编写程序。
11:59
1
A
B
C
11:59
2
• 解题思路:
– 要把64个盘子从A座移动到C座,需要移动大 约264 次盘子。一般人是不可能直接确定移动 盘子的每一个具体步骤的 – 老和尚会这样想:假如有另外一个和尚能有办 法将上面63个盘子从一个座移到另一座。那么, 问题就解决了。此时老和尚只需这样做:
11:59
11:59
37
#include <stdio.h> int main() { void hanoi(int n,char one, char two,char three); int m; printf(“the number of diskes:"); scanf("%d",&m); printf("move %d diskes:\n",m); hanoi(m,'A','B','C'); }
A
B
C
11:59
31
将2个盘子从B移到C的过程
A
B
C
11:59
32
将2个盘子从B移到C的过程
A
B
C
11:59
33
• 由上面的分析可知:将n个盘子从A座移到 C座可以分解为以下3个步骤:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
// algo3-10.cpp Hanoi塔问题,调用算法3.5的程序
#include<stdio.h>
int c=0; // 全局变量,搬动次数
void move(char x,int n,char z)
{ // 第n个圆盘从塔座x搬到塔座z
printf("第%i步: 将%i号盘从%c移到%c\n",++c,n,x,z);
}
void hanoi(int n,char x,char y,char z) // 算法3.5
{ // 将塔座x上按直径由小到大且自上而下编号为1至n的n个圆盘
// 按规则搬到塔座z上。
y可用作辅助塔座
if(n==1)
move(x,1,z); // 将编号为1的圆盘从x移到z
else
{
hanoi(n-1,x,z,y); // 将x上编号为1至n-1的圆盘移到y,z作辅助塔
move(x,n,z); // 将编号为n的圆盘从x移到z
hanoi(n-1,y,x,z); // 将y上编号为1至n-1的圆盘移到z,x作辅助塔
}
}
int main()
{
int n;
printf("3个塔座为a、b、c,圆盘最初在a座,借助b座移到c座。
请输入圆盘数:"); scanf("%d",&n);
hanoi(n,'a','b','c');
}。