汉罗塔问题

C语言复习——汉罗塔问题

①先理解一下最典型的递归问题:求n的阶乘

{
 int jc(int n);
 int n,y;
 printf("请输入n的值:");
 scanf("%d",&n);
 y=jc(n);
 printf("%d!=%d",n,y);
}
int jc(int n)
{
 int r;
 if(n ==  0||n== 1)
 r=1;
 else r=n*jc(n-1);
 return r;
 } 

理解递归思想可以从宏观和微观两个角度上来考虑:
(1)宏观:将定义的函数jc理解为一个黑匣子,只需知道它可以将算出n!即可。
(2)微观:体会黑匣子的工作过程。计算n!时需算n*(n-1)!,算(n-1)!时需算(n-1)(n-2)!并依次类推到最后n=2时,2=21!,而1!可以算出它为1,于是得出2!=2,返回上一层求出3!,再依次返回到n!并求出该值。
这就是递归的思想
②返回到汉罗塔问题
(1)先手动体会汉罗塔问题:
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
分析:n=1时,直接将A柱上一块,移到C柱上;n=2时,先将第一块移从A柱上移到B柱上,再将A柱上第二块移到C柱上,最后将B柱上的小块移到C柱上;n=3时,可以将过程理解为对n=2情况的模拟:先将上面两块从A柱移到B柱上(图中①②③步实现),再将最大的一块从A柱移到C柱上(第④步实现),最后将B柱上的两小块移到C柱上(⑤⑥⑦步实现);由此可知n=1是一种单独的情况,n>=2既是同一种情况。
(2)构造函数:
(1)宏观上:该函数看做一个黑匣子,它的功能是将一个块从一根柱移动到另一根柱
黑匣子内部需要调用自身,但要正确排版。
n=1时:函数可以直接将块由A柱移动到C柱
n>=2时:函数的作用是:第一步将n-1块板移动到B柱,第二步将第n块板移动到C柱,第三步将之前的n-1块板移动到C柱上。
关键:第一步和第三步都是对该函数自身的调用。

(2)微观上:

汉罗塔问题的本身是一个经典的递归;先看n=2的情况:

由于n>1,像计算n的阶乘一样,n=2时得先计算1!;所以这里一样先计算参数为1的情况,还是同计算阶乘一样,函数在参数为1时,都可以直接计算,jc(1)=1,而这里实现的是将块由一根柱移动到另一根柱上(一定要注意起始柱和末柱究竟是哪两个)。就n=2的情况,因为n=2>1所以执行else部分,move(n-1,A,C,B)可以直接计算,由于起始柱是A末柱是B,于是函数计算的结果就是实现了将块由A移动到B;返回上一层,继续执行else部分,需要将第二块由A移动到C,这里需要直接用printf函数直接实现,如果用编辑的move(n-1…),则在n>2时会出错,会使得这一步再一次调用本函数,出现多步,而这个位置永远只需要将最大的一块由A移动到C,所以直接printf实现;最后重复执行函数move(n-1,…),将之前的最小块由B移动到C即可,所以参数应该变为move(n-1,B,A,C),n-1=1还是可以就直接计算出将块由B移动到C。

n=2的情况就这样原原本本的实现了,于是就像计算阶乘一样,不断返回上一层,从而计算出不同的n的情况。
程序如下:

#include<stdio.h>
move(int n,char x,char y,char z)
{
 if(n==1)printf("%c-->%c\n",x,z);
      else {
       move(n-1,x,z,y);
       printf("%c-->%c\n",x,z);
       move(n-1,y,x,z);
   }
}
main()
{
 int n;
 scanf("%d",&n);
 move(n,'A','B','C');
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值