其他分享
首页 > 其他分享> > 汉诺塔问题的讨论

汉诺塔问题的讨论

作者:互联网

汉诺塔问题的讨论

what is it?

汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?

在这里插入图片描述
在这里插入图片描述

How to solve it

仔细分析这个问题,我们可以发现,当没有圆盘时,我们只要移动0步,圆盘为1时,我们只需要移动一步即可,圆盘为2时,我们需要移动三步即可。如果我们将n规模的问题都看成,1和n-1的问题,即我们把出去最下面一块的n-1块看成一个整体,那么解决这个问题我们只需要三步即可。

  1. 将n-1从A经C移到B
  2. 将最后一块从A移到C
  3. 将n-1从B经A移到C

这里我们可以用我们熟悉的递归去解决它,在递归中我们最关心的其实是递归出口,当n=0时f(n)=0; return;

/**
 * 有关汉诺塔问题我们可以,将一个复杂问题简单化,n规模的可以看成两个n-1规模的问题
 * f(n)=2f(n-1)+1; 时间复杂度O(n!)
 */
public class 汉诺塔 {
    public static void main(String[] args) {
        h(10,'A','B','C');
    }
    public static void h(int n,char a,char b,char c){
        if(n==0){
            return;//递归出口
        }
        h(n-1,a,c,b);
        System.out.println("把"+n+"从"+a+"移到"+c);
        h(n-1,b,a,c);
    }
}
public class Hanoi{
    public static void main(String[] args) {
        Stack<Integer> a=new Stack<>();
        Stack<Integer> b=new Stack<>();
        Stack<Integer> c=new Stack<>();
        for (int i = 0; i < 10; i++) {
            a.push(i);
        }
        print(a);
        reseve(10,a,b,c);
        print(c);
    }

    private static void print(Stack<Integer> a) {
        Iterator<Integer> it = a.iterator();
        while (it.hasNext()){
            System.out.print(it.next()+" ");
        }
        System.out.println();
    }

    private static void reseve(int i, Stack<Integer> a, Stack<Integer> b, Stack<Integer> c) {
        if (i==0) return;
        reseve(i-1,a,c,b);
        c.push(a.pop());
        reseve(i-1,b,a,c);
    }
}

  c.push(a.pop());
    reseve(i-1,b,a,c);
}

}


标签:讨论,圆盘,void,public,问题,汉诺塔,static,Stack
来源: https://blog.csdn.net/m0_50873883/article/details/121443679