• 死磕算法第二弹附加篇——汉诺塔


    汉诺塔

    栈的数据结构非常适合汉诺塔来解释,因为二者的操作原理是一样的,由此也衍生了针对汉诺塔的依稀额算法。其中一个就是三根柱子的汉诺塔的移动步骤。

    汉诺塔的移动原理

    这里我们详细的介绍一个汉诺塔的移动原理,假设三根柱子分别是A、B、C,一开始A上有N个圆盘,从小到大、从上到下分别是1、2......N-1、N,我们要把A上的N个圆盘远不移动到C上面,而每次只能移动每根柱子上面的一个圆盘。

    我们可以反过来考虑一下,若要把A上的圆盘全部移动到C上,那么需要把前N-1的盘子按照顺序落到B上了,最后的第N个圆盘才能够直接从A移动到C上,从而完成第N个圆盘的移动。之后把B的N-2个圆盘移动到A上,再把B上剩下的一个圆盘,也就是N-1个圆盘直接移动到C上,这是就已经完成最下面的两个圆盘的移动,继续这样的移动,直接就完成有洗。

    汉诺塔的递归实现

    上面的步骤在代码上使用递归是最好实现的,要使用递归,就要考虑到需要进行递归的部分是那部分。

    public class Hanoi {
        private static int moveNum = 0;
    
        private static void hanoi(int n, char a, char b, char c) {
            if (n == 1) {
                //如果只有一个圆盘,只需要移动就好
                move(a, c);
                return;
            }
            //先把A上的n-1个元哦按移动到B上
            hanoi(n - 1, a, c, b);
            //把A上的最后一个圆盘移动到C上
            move(a, c);
            //接下来递归,把B上的n-1个圆柱移动到C上
            hanoi(n - 1, b, a, c);
        }
    
        private static void move(char a, char c) {
            moveNum++;
            System.out.println(a + "--->" + c);
        }
    
        public static void main(String[] args) {
            hanoi(3,'A','B','C');
            System.out.println(moveNum);
        }
    
    }
    

    hanoi函数的第1个参数就是柱子上需要移动的元哦按的个数,后三个参数分别为一根柱子的标识。首先当n为1时,需要移动的圆盘只有一个,直接把A上的圆盘移动到C上就可以了,同时代码结束,因为已经没有需要移动的圆盘了。

    接下来就是实现汉诺塔实现的关键,即把A上的所有圆盘移动到C上,需要先把A最上面的n-1个圆盘移动到B上,于是有了“hanoi(n-1,a,c,b)”,就可以完成移动,这就是递归调用的思想所在了。

    在递归调用中会继续执行该方法,改变参数的值,继续打印,这样每次调用会减少n的值,直到n最后变为1之后,结束递归调用,最终完成汉诺塔移动。

    转变一下思想,就能够理解从B上移动n-1个圆盘到C上其实和从A上移动元哦按到C上是一样的。

  • 相关阅读:
    网络爬虫(抓取)正则表达式 (多线程协作)
    Asp.net 主题
    Asp.net 菜单控件
    CSS 布局Float 【4】
    CSS 布局Float 【3】
    CSS 布局Float 【2】
    CSS 布局Float 【1】
    CSS 布局Float 【0】
    Asp.Net 母版页
    Sql Server 远程过程调用失败
  • 原文地址:https://www.cnblogs.com/mr-cc/p/8659985.html
Copyright © 2020-2023  润新知