Hanoi汉诺塔步骤实现图示说明(C程序设计,例7.8)

2023-05-16

一 .题目:

古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上(如下图所示).有个老和尚想把这64个盘子从A座移到C座,但规定每一次只允许移动一个盘,且在移动过程中在3个座上都始终保持大盘在下,小盘在上.在移动过程中利用B座.要求变成输出移动盘子的步骤.

 

二 .解题思路分3步:

1.将A座上面n-1个盘子移到辅助的B座上;

2.将A座最下面的盘子移到C座上;     

3.将辅助的B座上的n-1个盘子移到C座上.

解释:

可以理解上面的3个步骤为1次"3步回归".

每次经过这3个步骤,只有第2步是有效的移动步骤.

第1步和第3步是回归操作,所以不用担心第1和3步骤有n-1个盘子要移动会很复杂,他们分别又是一个(比该步骤少一个盘子的)汉诺塔问题.要解决整个汉诺塔问题只需不断回归重复上述3个步骤就好了.(回归问题捋不明白的先去看简单的回归问题,看完书上例7.6,例7.7上机练习后基本就能明白了,看这个Hanio塔的问题也会更简单些)

 

 

 

三 .我以个人的理解重新画了图示表示上面3个步骤(上面n-1个盘子可以看作另一个完整的汉诺塔问题,所以用一个三角代替更加直观):

移动最下面的第n个盘子时的"3步回归":

 

接着下面递推倒数移动第n-1个盘子时的状态(横线下面代表已经移动好或者当前移动可以忽略的大盘子:因为大盘子可以一直在任意比它小的盘子下面,所以不用考虑它了)

以此类推......

有效移动第n-3个盘子

有效移动第n-4个盘子

有效移动第n-5个盘子

....

直到有效移动第1个盘子停止.


四 .实际上,上面只是该问题解题的一部分,因为每一个3步回归中都有第1步和第3步两个回归语句,所以Hanoi的回归线路不是像上面那样的线性的,而是二叉树状的.

(注:递归步骤是二叉树型的,但是所有程序执行都是线型从上至下执行的,下面会给出图示)

以下是移动4个盘子的Hanoi塔举例(下面是我画的完整的步骤图):

解释:

1.每一块便利贴上为1次"3步回归"(每一步的右上角有①,②等圆圈标号).

2.移动4个盘子共有7次"3步回归",即2^(n-1)次"3步回归".

3.一共有15次移动步骤,即2^n-1次移动步骤(书中统计得出的).

4.图中的流程线指的是程序线性执行步骤(左上角也画出来了).

 

回归步骤(上图左上角"递归图"):

第①个"3步回归":第一步:第②个"3步回归";

                           第二步:移动;

                           第三步:第⑤个"3步回归"

第②个"3步回归":第一步:第③个"3步回归";

                           第二步:移动;

                           第三步:第④个"3步回归"

第⑤个"3步回归":第一步:第⑥个"3步回归";

                           第二步:移动;

                           第三步:第⑦个"3步回归"

其中分支末端第③,④,⑥,⑦步的回归只有一步移动最上面的那个最小的盘子.

 

程序线性回溯步骤(上图左上角"程序执行图",理解递归原理的可以酌情跳过该步描述,递归包括2步:回溯和递推):

->递归的第1阶段:回溯

->第①步回归

->第②步回归

->第③步回归

->第②步回归的move

->第④步回归

->第①步回归的move

->第⑤步回归

->第⑥步回归

->第⑤步回归的move

->第⑦步回归(回溯结束)

->递归的第2阶段:递推步骤(从最末端反向线性执行程序,只筛出具体执行移动的步骤)

->第⑦步执行

->第⑤步move执行

->第⑥步执行

->第①步move执行

->第④步执行

->第②步move执行

->第③步执行(递推结束)

 

五.抽象化问题并编写程序:

题目要求输出移动步骤,抽象化"3步回归"(假设每步有n个盘子,每次只移动1个盘子,把上面n-1个盘子当成1个盘子,所以就用移动1个盘子的步骤代替每一步的描述):

1.A->B(移动个n-1个盘子)

2.A->C(移动个1个盘子)

3.B->C(移动个n-1个盘子)

程序思路:

把"3步回归"抽象为一个hanoi回归函数:

1.一般递归问题的函数都要有个输入求第几个的数的参数,Hanoi塔中即移动盘子的个数n.

2.每次移动按功能分3个功能位置:初始位置,辅助位置,目标位置.分别对应函数中的3个参数a,b,c.

3.功能位置参数a,b,c开始时分别用'A' 'B' 'C'赋值,'A','B','C'3个值分别代表3个底座.

4."3步回归"中参数值的变化规律(如图中第①步回归和第②步回归的"3步回归"的右侧总结的规律):

               

       初始a,b,c位置参数值 : a='A',b='B',c='C';

       第1步 : A->B,a='A',b='C',c='B';     //把上面n-1个盘子从A座移动到B座上(借助C座),所以初始a='A',辅助b='C',目标c='B'.

       第2步 : A->C;                               //把当前hanoi塔问题中最大的1个盘子从A座移动到C座上.

       第3步 : B->C,a='B',b='A',c='C';     //把上面n-1个盘子从B座移动到C座上(借助A座),,所以初始a='B',辅助b='A',目标c='C'.

 

 

编写函数:

move函数为(有效移动步骤,在程序中负责输出每一步,比如"A->B"):

void move(char start,char aim)        //start:移动起点,aim:移动终点
{
    printf("%c -> %c\n",start,aim);
}

hanoi函数为:

void hanoi(int n,char a,char b,char c)  //a:原位置,b:辅助,c:目标位置
{
    hanoi(n-1,a,c,b);
    move(a,c);
    hanoi(n-1,b,a,c);
}

由于递归移动到第一个最小的盘子后截至,输入的盘子序号也不能<1,所以hanoi函数需要增加判断条件:

void hanoi(int n,char a,char b,char c)  //a:原位置,b:辅助,c:目标位置
{
    if(n<1)printf("n<0,data error!");   //输入的盘子序号<1,报错
    else if(n==1) move(a,c);            //当盘子为第一个最小的盘子时,直接进行移动,此次递归结束
    else
    {
        hanoi(n-1,a,c,b);
        move(a,c);
        hanoi(n-1,b,a,c);
    }
}

完整的代码:

操作:输入n,输出一些文字提示.

#include <stdio.h>
int main()
{
    int n;
    printf("Print the num of disk: ");
    scanf("%d",&n);
    hanoi(n,'A','B','C');
    return 0;
}
void hanoi(int n,char a,char b,char c)  //a:原位置,b:辅助,c:目标位置
{
    if(n<1)printf("n<0,data error!");   //输入的盘子序号<1,报错
    else if(n==1) move(a,c);            //当盘子为第一个最小的盘子时,直接进行移动,此次递归结束
    else
    {
        hanoi(n-1,a,c,b);
        move(a,c);
        hanoi(n-1,b,a,c);
    }
}
void move(char start,char aim)
{
    printf("%c -> %c\n",start,aim);
}

注:题目为移动64个盘子,需要移动2^n-1次,假如每一步移动1s,需要2^n-1s,大概600亿年.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hanoi汉诺塔步骤实现图示说明(C程序设计,例7.8) 的相关文章

  • 在linux虚拟机上安装docker

    1 简介 Docker是一个开源的应用容器引擎 xff1b 是一个轻量级容器技术 xff1b Docker支持将软件编译成一个镜像 xff1b 然后在镜像中各种软件做好配置 xff0c 将镜像发布出去 xff0c 其他使用者可以直接使用这个
  • win11虚拟机如何安装 Windows11虚拟机安装步骤教程

    想要体验下最新的win11系统 但是又不想在实体机上安装 担心出现系统故障问题怎么办 我们可以通过虚拟机安装win11系统实现 下面小编就教下大家虚拟机如何安装win11系统 更多Windows11系统教程可以参考小白一键网 1 下载安装好
  • Win11如何开启移动热点?Win11开启移动热点的方法

    在Win10系统之后就有了一个移动热点功能 xff0c 这在Win11系统也不例外 xff0c 不过很多小伙伴并不清楚Win11系统中的移动热点功能如何开启 xff0c 那么下面就和小编一起来看看Win11开启移动热点的方法 xff0c 有
  • 交换机组建局域网

    说来惭愧 xff0c 今天才搞明白用交换机组建局域网的原理 xff0c 这里介绍方法 xff1a 平时使用的路由器有交换机的功能 xff0c 单纯使用交换机还是第一次 xff1a 1 将所有电bai脑连到同一台交换机上 xff0c du即将
  • mavros 使用经验记录

    我用的飞控硬件板是pixhawk xff0c 用missionplanner刷的fight stack是apm的最新版本3 4 amp对mavros支持不是特别好 xff0c 如果合适还是用px4的flight stack 比较好 xff0
  • ros catkin_make 出现add_custom_target cannot create target 错误

    今天用catkin make编译ros包出现如下错误 CMake Error at home liwei work catkin ws land build mycommbase cmake mycommbase genmsg cmake
  • mavros使用经验记录二

    项目是一个无人机视觉追踪功能 xff0c 无人机上的协从计算机通过串口连接到飞控的tel2 接收mavlink消息流 xff0c 协计算机将此mavlink流进行udp转发到地面站 xff0c 同时协计算机实时的进行图像处理 xff0c 将
  • Unix Shell中单引号、双引号字符、反斜杠、反引号的使用

    在执行shell脚本的时候 xff0c shell将会对脚本中的行进行解释 xff0c 然后执行 xff1b 对于一些特殊处理的句子 xff0c 我们可以使用引号或者反斜线来避免shell解释执行之 如下 xff0c 当在命令行中输入 xf
  • TX2 Ubuntu 系统默认root用户登录 (永久权限)

    操作简单 xff0c 亲测可行 xff0c 不需要写啥脚本 https jingyan baidu com article 6181c3e0780131152ef153ff html
  • nginx部署多个vue项目的2种方法

    第一种 同一个域名或者ip 相同端口号 部署多个项目 通过斜线访问 http 10 16 xx 23 student http 10 16 xx 23 先看这2种配置 查找nginx 和配置文件 whereis nginx 查看配置文件 v
  • 用C++写一个简单的服务器(Linux)

    用C 43 43 写一个简单的服务器 Linux 下面是创建一个简单服务器的基本流程 xff0c 所用的端口是8099 后面贴了代码 一 基本流程 xff1a 创建套接字配置服务器地址相关参数将两者绑定监听套接字上的端口在上面创建的套接字上
  • Resource not found: roslaunch的解决方法

    文章目录 问题解决办法 问题 按照ROS教程学习时 xff0c 在运行roscore时出现问题 roscore Resource not found roslaunch ROS path 0 61 opt ros noetic share
  • Cannot load command parameter [robot_description]解决方法

    在github上下载一个ros仿真小车 xff0c 运行时 Invalid tag Invalid tag Cannot load command parameter robot description 参考 https wiki ros
  • ORB_SLAM2 ROS Example 编译 CMake Error at CMakeLists.txt:37 (message): OpenCV > 2.4.3 not found解决办法

    报错 CMake Error at CMakeLists txt 37 span class token punctuation span message span class token punctuation span OpenCV s
  • ORB_SLAM2_modified编译

    CMake Error at CMakeLists txt 37 message OpenCV gt 2 4 3 not found Configuring incomplete errors occurred ORBSLAM2 with
  • 导纳控制 admittance control

    简单记录一下导纳控制 对于一个质量块 m m m xff0c 其位移记为 x x x xff0c 我们期望它按照预期保持在
  • T-S模糊模型与状态反馈控制及Matlab仿真 (附代码)

    目录 一 仿射非线性系统建模 二 计算T S模糊模型子系统 三 建立推理 xff0c 验证开环特性 四 极点配置 xff0c 验证闭环特性 五 使用LMI验证稳定性 一 仿射非线性系统建模 以overhead crane system为例
  • 2022同济825自控原理

    1 求 R L C RLC R L C 电路的传递函数 2 求 M a s
  • json离线解析格式化工具

    json离线解析格式化工具 xff1a 当没有网络的时候 xff0c 可以使用该工具实现json解析格式化 https download csdn net download boboelec 11992955 工具使用效果 xff1a
  • LMI 转化与Matlab工具箱

    目录 一些结论 1 1 中给出下面两结论 lmivarcase1case2case3case4 参考 需要将一些不等式转化为LMI 一些结论 1 1 中给出下面两结论 P gt 0

随机推荐

  • Err:1 http://security.ubuntu.com/ubuntu bionic-security InRelease Could not resolve ‘security.ubun

    在执行apt get update命令的时候更新报错 Err 1 http security ubuntu com ubuntu bionic security InRelease Could not resolve 39 security
  • 强化学习Q-Learning算法

    强化学习Q Learning算法 前言基本概念基本概念递推关系 Q learning基本原理注意事项局限性仿真 前言 学习这个算法有一段时间了 xff0c 但是因为自己犯懒一直没有整理 现整理一下 xff0c 一方面有刚入门的同学可以参考
  • 联想拯救者Y7000P装win10与Ubuntu18.04双系统

    初衷 写这个博客的初衷是为了记录本人在联想笔记本上安装Ubuntu18 04双系统时遇到的坑 xff0c 事后装完之后发现并不是很坑 xff0c 但是如果没有遇到过此类问题 xff0c 就很难受了 xff0c 所以决定记录下来 这款笔记本安
  • 强化学习DDPG算法

    强化学习DDPG算法 前言 因为疫情一直在辗转隔离 xff0c 没心思学习 xff0c 索性整理一下学过的东西 xff0c 记一下学习笔记 xff0c 就当自我安慰了 推导部分观看了这个B站的学习视频 DDPG 与DQN不同 xff0c D
  • 最优控制 3:最优控制理论中的极小值原理与动态规划

    最优控制 3 xff1a 使用极小值原理求解最优控制问题 引言极小值原理 t f t f t f 固定的情况
  • 使用Pycharm创建一个工程

    刚刚开始学习Python xff0c 使用的IDE是PyCharm 本来想记在本子上 xff0c 可是感觉有点慢 xff0c 而且多 xff0c 因此选择在网上记录自己的笔记 哈哈 xff0c 也不知道能记多长时间 PyCharm下载安装之
  • Pycharm在windows下使用Anaconda中的Python解释器各种报错的问题

    最近几天被windows下的软件快要搞疯了 电脑装了Anaconda3 xff0c 在运行一些python程序的时候 xff0c 这些程序在anaconda的自带终端中python代码可以正常运行 但是不可以使用诸如Pychrm和VS201
  • Ubnutu16.04 系统下编译PX4固件方法

    今天开始准备在Ubuntu16 04下搭建PX4的开发环境 早就听说源代码编译的过程中有很多坑 xff0c 所以在编译源代码之前在网上搜索了很多教程 xff0c 其中这个教程写的非常详细 xff1a https blog csdn net
  • 高斯过程回归中后验概率的简单推导

    最近几天在整理高斯过程回归 Gaussian Process Regression GPR 部分的知识 xff0c 虽然还有很多问题没有搞懂 xff0c 但是有一点进展还是决定总结下来 xff0c 防止遗忘 在整理之前 xff0c 先列出我
  • mavlink增加自定义消息

    mavlink作为PX4以及APM两大开源飞控的通讯协议 xff0c 应用非常广泛 在进行开源飞控二次开发时 xff0c 增加自定义消息非常普遍 比如在offboard模式下 xff0c 将视觉避障信息或者雷达信息发送给飞控 xff0c 这
  • 【从0到1】组装深度学习台式机

    本文旨在为有从事深度学习研究的同学提供一份装机攻略 xff0c 望对您有帮助 1 前言 目前 新基建 热潮 xff0c 人工智能如火如荼 xff0c 国内大部分院校 企业都会为学生 员工配置实验集群 xff0c 但是有时候想在本地自己跑些d
  • 【ROS学习】节点运行管理launch文件的基本操作

    launch文件的概念和作用 launch 文件是一个 XML 格式的文件 xff0c 可以启动本地和远程的多个节点 xff0c 还可以在参数服务器中设置参数 launch文件的作用是 xff1a 简化节点的配置与启动 xff0c 提高RO
  • 系统提示“该设备无法启动(代码:10)”,USB设备不能开始工作怎么办?

    文章来源 xff1a https www reneelab com cn this device cannot start html 目录 原因分析解决方法一 xff1a 在设备管理器中更新驱动程序解决方法二 xff1a 重新安装有问题的U
  • printf 在Linux终端上输出彩色字体 (串口也适用)

    有时我们希望在LINUX终端上按照调试级别打印不同颜色的调试信息 xff0c 如 include lt stdio h gt define DBG PRINT format arg do fprintf stdout 34 ld d fla
  • vSLAM重读(4): OKVIS--KeyFrame-based Visual-Inertial SLAM

    1 摘要 视觉传感器与IMU传感器互补 61 61 gt VIO系统 xff1b 由最初的以滤波为主题 xff0c 现在逐渐转换为非线性优化来实现SLAM xff1b 提出一种方法将视觉信息与IMU测量数据紧密结合 xff0c 将IMU的误
  • vSLAM重读(5): vSLAM中对双目相机的数据处理及与单目相对比

    1 双目相机概述 双目立体视觉模型 双目模型求取深度 双目立体相机分别校准可参考 ROS 单目相机 分别校准 双目立体匹配算法案例 https www cnblogs com riddick p 8486223 html https www
  • ROS回顾学习(11): TF之static_transform_publisher

    主要用于静态坐标转换 两种发布形式 1 俯仰角 43 位置坐标 span class token comment static transform publisher x y z yaw pitch roll frame id child
  • 菜鸟专学:从头到尾创建自己的SLAM系统

    RobotSlamApplication项目二 xff1a 小型SLAM系统 研究背景 xff1a 因为之前比较浮躁 xff0c 总是喜欢研究别人的库然后测试跑通 xff0c 效果好就拿来修修改改 然后测试测试就用 xff0c 效果不好就抛
  • 伽马分布与 贝塔分布

    伽马函数 称 为伽马函数 xff0c 其中参数 xff0c 伽马函数具有如下性质 xff1a n为自然数 xff1b 或写作 余元公式 xff1a 对于 有 与贝塔函数 的关系 对于 伽马函数是严格凹函数 x足够大时 xff0c 可以用St
  • Hanoi汉诺塔步骤实现图示说明(C程序设计,例7.8)

    一 题目 古代有一个梵塔 塔内有3个座A B C 开始时A座上有64个盘子 盘子大小不等 大的在下 小的在上 如下图所示 有个老和尚想把这64个盘子从A座移到C座 但规定每一次只允许移动一个盘 且在移动过程中在3个座上都始终保持大盘在下 小