简单递归—Hanoi(汉诺塔问题)

这是一个关于解决汉诺塔问题的C++程序。通过递归函数`Hanoi`,将n个盘子从柱子a移动到柱子c,借助柱子b。程序中,`Hanoi`函数首先移动n-1个盘子到中间柱子,然后将最底下的盘子移动到目标柱子,最后再将剩余的n-1个盘子借助初始柱子移动到目标柱子。在主函数中,用户可以输入不同数量的盘子进行移动操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:
有N个圆盘,依半径大小(半径都不同),自下而上套在A柱上,每次只允许移动最上面一个盘子到另外的柱子上去(除A柱外,还有B柱和C柱,开始时这两个柱子上无盘子),但绝不允许发生柱子上出现大盘子在上,小盘子在下的情况,现要求设计将A柱子上N个盘子搬移到C柱去的方法。
 
问题分析:
    本题是典型的递归程序设计题。
    (1)当N=1 时,只有一个盘子,只需要移动一次:A—>C;
    (2)当N=2时,则需要移动三次:
        A------ 1 ------> B,       A ------ 2 ------> C,       B ------ 1------> C. 
    (3)如果N=3,则具体移动步骤为:
      1.from A to C
      2.from A to B
      3.from C to B
      4.from A to C
      5.from B to A
      6.from B to C
      7.from A to C
      假设把第3步,第4步,第5步,第七步 抽出来就相当于N=2的情况(把上面的2片捆在一起,视为一片)
  原问题:欲将A柱上的N片移动到C柱上,B柱为过渡柱,记为(A,B,C)
  1.将A柱上的(N-1)片移到B上,{A为原柱,B为目标柱,C为过渡柱,记为(A,B,C)}
  2.将A柱上剩下的1片直接移到C柱上
  3.将B上的(N-1)片移到C上,结束。{B为原柱,C为目标柱,A为过渡柱,记为(B,C,A)}
  所以可按“N=2”的移动步骤设计:
       ①如果N=0,则退出,即结束程序;否则继续往下执行;
       ②用C柱作为协助过渡,将A柱上的(N-1)片移到B柱上,调用过程Hanoi(n-1, a,b,c);
       ③将A柱上剩下的一片直接移到C柱上;
       ④用A柱作为协助过渡,将B柱上的(N-1)移到C柱上,调用过程Hanoi (n-1,b,c,a)。
 
我的代码:

#include<stdio.h>
#include<iostream>
using namespace std;
int k=0;
void Hanoi(int n,char a,char c,char b)
{  
    if(n==0) return;
    Hanoi(n-1,a,b,c); //借助 b 柱子,先将 n-1个盘子放在 b柱子上
    k++;             //输出一次,k就加一,k必须要写在这里 ,因为上面一步也是递归,如果 k++写在它上面 k 将会加好多次,在输出时k就不是从1开始了。
    //cout <<k<<" :from "<<a <<"-->"<<c<<endl;
    printf("%d:from %c --> %c\n",k,a,c);    //再将 a 上的剩下的1个盘子搬到 c 柱子上 ,输出移动过程
    Hanoi(n-1,b,c,a);    //然后再借助 a 柱子,将 b柱子上的 n-1 个盘子搬到 c 柱子上
}
int main()
{
    int  n;       //表示共有几个盘子
    char  a,b,c; //三个柱子:a,b,c
    while(scanf("%d",&n)!=EOF)
    {
    Hanoi(n,'a','b','c');
    k=0;
    }
    return 0;

程序定义了把n片从A柱移到C柱的过程Hanoi (n,a,c,b),这个过程把移动分为以下三步来进行:
       ①先调用过程Hanoi(n-1, a, b, c),把(n-1)片从A柱移到B柱, C柱作为过渡柱;
       ②直接执行 writeln(a, ’-->’, c),把A柱上剩下的一片直接移到C柱上,;
       ③调用Hanoi (n-1,b,c,a),把B柱上的(n-1)片从B移到C柱上,A柱是过渡柱。
       对于B柱上的(n-1)片如何移到C柱,仍然调用上述的三步。只是把(n-1)当成了n,每调用一次,要移到目标柱上的片数N就减少了一片,直至减少到n=0时就退出,不再调用。exit是退出指令,执行该指令能在循环或递归调用过程中一下子全部退出来。
       Hanoi过程中出现了自己调用自己的情况,在Pascal中称为递归调用,这是Pascal语言的一个特色。对于没有递归调用功能的程序设计语言,则需要将递归过程重新设计为非递归过程的程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值