• n阶汉诺塔问题(Hanoi)


    问题描述


    • 假设有3个分别命名为X、Y、Z的塔座
    • 在塔座X上插有n个直径大小各不相同、依小到大编号为1,2,...,n的圆盘。
    • 现要求将X轴上的n个圆盘移至塔座Z上并仍按同样顺序叠排
    • 圆盘移动时必须遵循下列规则:
      1. 每次只能移动一个圆盘
      2. 圆盘可以插在X、Y、Z中的任一塔座上
      3. 任何时刻都不能将一个较大的圆盘压在较小的圆盘之上


    算法思想


    • 当n=1时
      • 问题比较简单,只要将编号为1的圆盘从塔座X直接移至塔座Z上即可;
    • 当n>1时
      • 需利用塔座Y作辅助塔座,若能设法将压在编号为n的盘之上的n-1个圆盘从塔座X移至塔座Y上
      • 然后将编号为n的圆盘从塔座X移至塔座Z上
      • 最后再将塔座Y上的n-1个圆盘移至塔座Z上
      • 而将n-1个圆盘移至塔座Z上又相当于一个新的汉诺塔问题,这一次是以X为辅助塔座
      • 循环往复,总是以X和Y这两个为辅助塔座
    • 简言之(参考链接
      • 首先以Z为辅助塔座将n-1个圆盘移动Y
      • 将编号为n的圆盘移至塔座Z
      • 再将剩余的n-1个圆盘移至塔座Z


    C语言伪代码表示的算法


    void hanoi(int n, char x, char y, char z){
        // 将塔座x上按直径由小到大且自上而下编号为1至n的n个圆盘按规则搬到
        // 塔座z上,y可用作辅助塔座
        // 搬动操作move(x, n, z)可定义为(c是初值为0的全局变量,对搬动计数):
        // printf("%i. Move disk % i from %c to %c\n", ++c, n, x, z);
        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作辅助塔
        }
    }
    

    Java


    • 源码
    /**
     * 汉诺塔算法实现
     * @param n 圆盘的数量
     * @param x X塔座
     * @param y Y塔座
     * @param z Z塔座
     */
    public void hanoi (int n, char x, char y, char z) {
        if (1 == n) {
            move(x, 1, z);
        } else {
            hanoi(n-1, x, z, y);
            move(x, n, z);
            hanoi(n-1, y, x, z);
        }
    }
    
    /**
     * 打印出移动过程
     * @param x X塔座
     * @param n Y塔座
     * @param z Z塔座
     */
    public static final void move (char x, int n, char z) {
        System.out.println("将编号为" + n + "的圆盘从" + x + "塔座放到" + z + "塔座");
    }
    
    • 测试用例
    @Test
    public void testHanoi () {
        hanoi (3, 'X', 'Y', 'Z');
    }
    
    • 测试结果
    将编号为1的圆盘从X塔座放到Z塔座
    将编号为2的圆盘从X塔座放到Y塔座
    将编号为1的圆盘从Z塔座放到Y塔座
    将编号为3的圆盘从X塔座放到Z塔座
    将编号为1的圆盘从Y塔座放到X塔座
    将编号为2的圆盘从Y塔座放到Z塔座
    将编号为1的圆盘从X塔座放到Z塔座
    

    Python


    • 源码
    def move(n, a, b, c):
    	if n == 1:
    		print a, '-->', c
    	else:
    		move(n-1, a, c, b)
    		print a, '-->', c
    		move(n-1, b, a, c)
    
    • 测试用例
    move(3, 'A', 'B', 'C')
    
    • 测试结果
    A --> C
    A --> B
    C --> B
    A --> C
    B --> A
    B --> C
    A --> C
    
  • 相关阅读:
    UI 常用方法总结之--- UITableView
    UITextFiled 通知监听
    ios 本地通知
    AFNetworking 请求头的设置
    UI总结
    gitlab-server环境搭建
    redis 配置文件示例
    搭建spark集群
    kafka集群安装
    zookeeper集群搭建
  • 原文地址:https://www.cnblogs.com/freelancy/p/7918469.html
Copyright © 2020-2023  润新知