递归和循环----汉诺塔

题目:
  • 汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
    有两个限制条件,第一个是每次只能够移动一个圆盘,第二个是大圆盘只能在小圆盘下面
思路:
  1. 如果1个盘子,你直接可以从第一根柱子移动到最后一根柱子就可以了
  2. 如果有两个盘子,第一你需要先把上面的盘子,从start柱子移动到middle柱子去,第二需要把下面的盘子,移动到最后那个盘子中最后那个柱子上,最后把上面的盘子从middle柱子上移动到end柱子上。
  3. 假设n个盘子,即函数f(n),第一步把上面的n-1盘子通过end那个空柱子最终移动到middle柱子,第二步把下面的大盘子移动到end柱子上去,第三步把上面的n-1个盘子通过start这个空柱子按照限制条件移动到end柱子上去
   /**
     *  汉诺塔
     *  
     * @param n 盘子的数量
     * @param start 开始柱子
     * @param middle 中介柱子 也就是那个空闲柱子
     * @param end  放结果柱子 也就是你通过移动,将这个盘子移动到哪个柱子上
     * 树的中序遍历
     */
    public static  void hanoi(int n,int start,int middle,int end){
        if (n <= 1){
            System.out.println(start + "---->" +end);
        }else{
            hanoi(n-1,start,end,middle);
            System.out.println(start + "---->" +end);
            hanoi(n-1,middle,start,end);

        }
    }
    
    // 测试用例
     hanoi(3,1,2,3);
   // 打印结果:
     1---->3
     1---->2
     3---->2
     1---->3
     2---->1
     2---->3
     1---->3
小结

汉诺塔的时间复杂度是指数级别的,分析如下:假设我们要挪动n个圆盘,记为T(n),首先需要挪动n-1个圆盘,记为T(n-1),然后再挪动1个圆盘,记为O(1),最后还需要再挪动n-1个圆盘,这样的话的T(n)=2*T(n-1) + O(1),
这个公式解出来的话,也就是 T(n)=2^n.
也就是说每增加挪动一个圆盘,移动步骤几乎是之前的两倍

你可能感兴趣的:(算法)