zoukankan      html  css  js  c++  java
  • 汉诺(hanio)塔问题


    规则:大盘子不能压在小盘子上。
    要求:将A柱子上所有盘(每个盘大小不同)放到C柱子上,使用B柱子作辅助。


    比如柱子A上有n个盘,执行以下步骤:
    1. 把n-1个盘从源柱移动到临时柱上;
    2. 把源柱上剩余的1个盘移动到目标柱上;
    3. 把临时柱上的n-1个盘移到目标柱上。

    显然,以上步骤将问题的规模缩小了一点。没有直接移动n个盘,而是移动n-1个盘。
    那么,对于任务1和任务3来说,其性质显然和原问题是一样的,只是需要移动的盘子的数量减少了。
    那么,对于任务1和任务3,可以用解决原问题的方法解决它们。这样不断重复下去,问题规模不断缩小,到最后变成了举手之劳,这样形成了递归模型。递归模型为hanio(int n, char source, char temp, char target)。num为当前任务需要移动的盘子的个数,source, temp, target用于指定三种类型的柱子。

    为了写出代码,拿任务1作具体演绎:
    1.1把n-1个盘从源柱移动到临时柱上;
      2.1把n-2个盘从源柱移动到临时柱上;
        3.1把n-3个盘从源柱移动到临时柱上;
          …
        3.2把源柱上剩余的1个盘移动到目标柱上;
        3.3把临时柱上的n-3个盘移到目标柱上。
      2.2把源柱上剩余的1个盘移动到目标柱上;
      2.3把临时柱上的n-2个盘移到目标柱上。
    1.2把源柱上剩余的1个盘移动到目标柱上;
    1.3把临时柱上的n-1个盘移到目标柱上。

    移动是在两个位置之间移动,因此只需要两个参数。定义第一个参数位置始终为每个步骤的起点,第三个参数位置始终为每个步骤的终点。变量source, temp, target的初值分别为'A', 'B', 'C'。
    递归的终点是:把1个盘从源柱移动到目标柱上。

    void hanio(int n, char source, char temp, char target)
    {
        if(n == 1)//递归的终点 
        move(source, target);
        else{
            //下面的代码是对文章开头步骤的复述
            hanio(n-1, source, target, temp);
            move(source, target);
            hanio(n-1, temp, source, target);
        }
    }

    完整代码如下:

    #include <stdio.h>
    void hanio(int n, char source, char temp, char target);
    void move(char x, char y);
    
    int main()
    {
        int num = 3;
        hanio(num, 'A', 'B', 'C');
        return 0;
    }
    void hanio(int n, char source, char temp, char target)
    {
        if(n == 1)//递归的终点 
            move(source, target);
        else{
        //下面的代码是对文章开头步骤的复述
            hanio(n-1, source, target, temp);
            move(source, target);
            hanio(n-1, temp, source, target);
        }
    }
    
    void move(char x, char y)
    {
        printf("%c--->%c
    ", x, y);
    } 

    不建议继续作微观思考,显然模型已经构造完毕。如果非要深入演绎,此处可以举个例子。
    从上往下看,先看第一个任务:把n-1个盘从源柱移动到临时柱上。
    这个任务重新表述为:把n-1个盘从源柱A移动到临时柱B上。
    由于要达成把n-1个盘从源柱移动到临时柱B上这个目标,原问题中的临时柱B显然已经成为了本任务中的目标柱,而C柱本来在原问题中是目标柱,现在在这个任务中也就成了临时柱,源柱是A柱。
    这里B和C发生了交换。A--源柱,B--目标柱,C--临时柱。

    为了完成第一个任务,先要完成第二个任务:把n-2个盘从源柱移动到临时柱上。

    我们来看第二个任务。
    这个任务重新表述为:把n-2个盘从源柱A移动到临时柱C上。
    在这个任务中,C柱俨然是目标柱,而B柱只好是临时柱了。
    A--源柱,B---临时柱,C-目标柱。
    这里,B和C又发生了交换,角色换回来了,和原问题的各柱扮演的角色一样,这样不断交换下去。
    不信看第三个任务:把n-3个盘从源柱移动到临时柱上。
    这个任务重新表述为:把n-2个盘从源柱A移动到临时柱B上。
    那么B又成了目标柱。。。

  • 相关阅读:
    sql函数
    sql日期
    Windows下串口编程
    Libreoffice/Office:禁止首字母自动大写功能
    convert:图片转pdf失败
    LibreOffice/Calc:单元格设置下拉菜单
    Ubuntu:查询计算机软硬件信息
    tar:文件打包归档
    中科大自主招生2018年笔试数学之五
    文件分割与合并
  • 原文地址:https://www.cnblogs.com/feicaixian/p/9721768.html
Copyright © 2011-2022 走看看