汉诺塔问题

来源:互联网 发布:head first python下载 编辑:程序博客网 时间:2024/06/12 23:37

一、汉诺塔的图解递归算法
1、问题起源:
汉诺塔(又称为河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子从上往下按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始案大小顺序重新排放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
2、数学描述:
如图所示,从左到右由A,B,C三根柱子,其中A柱子上面由从小叠到大的n个圆盘,现在要求将A柱子上的圆盘移动到C柱子上,期间只有一个原则:一次只能移动一个盘子,并且大盘子不能在小盘子上面,求移动的步骤和 移动的次数。
这里写图片描述

解:
(1)n==1
第一次 1号盘 A –>C sum =1次
(2)n==2
第一次 1号盘 A –>B
第二次 2号盘 A –>C
第三次 1号盘 B –>C sum =1次
(3)n==3
第一次 1号盘 A –>C
第二次 2号盘 A –>B
第三次 1号盘 C –>B
第四次 3号盘 A –>C
第五次 1号盘 B –>A
第六次 2号盘 B –>C
第七次 1号盘 A –>C sum =7次
移动次数:n个圆盘移动的次数为:2^n -1

3.算法分析:(递归 )
当只有一个盘子时,只需要将A塔上的一个盘子移动到C塔上即可;
当A塔上有2盘子时,先将A塔上编号1(编号从上往下递增)的盘子移动到B塔上,然后将A上的2号盘子(最大的盘子)移动到C塔上,最后将B塔上的1号盘子移动到C塔上。
当A塔上有3个盘子时,先将编号1-2两个盘子移动到B上(借助C塔),然后将A塔上剩余的最大的盘子3号移动到C塔上,最后将B塔上的1-2号盘子移动到C塔上(借助A塔)。
。。。
当A塔上有n个盘子时,先将编号为1至n-1的盘子(共n-1个)移动到B塔上(借助C塔),然后将塔上的剩余一个即编号为n的盘子移动到C塔上,最后将B塔上的那n-1个移动到C塔上(借助A塔)。
综上所述:除了n==1时,不需要借助其他塔,直接移动,其余情况都一样。
代码:

package towerOfHanoi;import java.util.Scanner;/** * 汉诺塔问题 * 基本思路: *  (1)把n-1个盘子由A移动到B(借助C); *  (2)把第n个盘子由A移动到C; *  (3)把n-1个盘子由B移动到C(借助A); * */public class ToowerOfHanoi {    static int m = 0;//标记移动的次数    //实现移动的方法    public static void move(int disks,char N,char M){        System.out.println("第"+(++m)+" 次移动: "+"把 "+disks+"号盘从"+N +"->移动到->"+M);    }    /**     *      * @param n 要移动的盘子总数     * @param A 盘子所在的塔号     * @param B 需要借助的塔号     * @param C 盘子要被移到的塔号     */    public static void hanoi(int n,char A,char B,char C){        if(n ==1){            //当只需要移动一个盘子时            move(1,A,C);            return;        }        hanoi(n-1,A,C,B);//把n-1个盘子由A移动到B(借助C);        move(n,A,C);//把第n个盘子由A移动到C;        hanoi(n-1,B,A,C);//把n-1个盘子由B移动到C(借助A);    }    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        char A = 'A';        char B = 'B';        char C = 'C';        System.out.println("这是汉诺塔问题: 把A塔上编号从小到达的圆盘通过辅助塔B移动到塔C上");        System.out.println();        System.out.println("请输入圆盘的个数:");        int disks = sc.nextInt();        ToowerOfHanoi.hanoi(disks, A, B, C);        System.out.println(">>移动了"+ToowerOfHanoi.m+"次,把A塔上的盘子移动到了塔C 上");        sc.close();    }}运行结果:这是汉诺塔问题: 把A塔上编号从小到达的圆盘通过辅助塔B移动到塔C上请输入圆盘的个数:31 次移动: 把 1号盘从A->移动到->C第2 次移动: 把 2号盘从A->移动到->B第3 次移动: 把 1号盘从C->移动到->B第4 次移动: 把 3号盘从A->移动到->C第5 次移动: 把 1号盘从B->移动到->A第6 次移动: 把 2号盘从B->移动到->C第7 次移动: 把 1号盘从A->移动到->C>>移动了7次,把A塔上的盘子移动到了塔C 上
0 0
原创粉丝点击