算法详解--汉诺塔

算法由来
小故事
汉诺塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家Edouard Lucas曾提及这个故事,据说创世
纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根
石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。

我们来把这个故事变成一个算法:
把三个柱子标为ABC 如果只有一个盘子时,将它直接搬到c,当有两个盘子,就将B做为辅助。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两个盘子,也就是
A->B A->C B->C这三个步骤,而被遮住的部分是一个递归处理。如果有n个盘子,则移动完毕所需的次数为2^n-1。

如图:

事实上,若有n个盘子,则移动完毕所需之次数为2^n - 1,所以当盘数为64时,则所需次数为:

264- 1 = 18446744073709551615

为5.05390248594782e+16年,也就是约5000世纪,如果对这数字没什么概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右。
java代码实现:

package algorithm;

public class TowersofHanoi {
public static void main(String[] args) {
    alogr(4, 'a', 'b', 'c');

}
public  static void alogr(int n ,char a ,char b ,char c){
    if(n==1){
         System.out.println("盘 " + n + " 由 " + a + " 移至 " + c);
        return;
    }else {
        alogr(n-1, a, c, b);
         System.out.println("盘 " + n + " 由 " + a + " 移至 " + c);
         alogr(n-1, b, a, c);
    }


}
}

运行效果当n=4的时候

1a 移至 b
盘 2a 移至 c
盘 1 由 b 移至 c
盘 3a 移至 b
盘 1 由 c 移至 a2 由 c 移至 b
盘 1a 移至 b
盘 4a 移至 c
盘 1 由 b 移至 c
盘 2 由 b 移至 a1 由 c 移至 a3 由 b 移至 c
盘 1a 移至 b
盘 2a 移至 c
盘 1 由 b 移至 c

Hanoi塔问题, 算法分析如下
设A上有n个盘子。
如果n=1,则将圆盘从A直接移动到C。
如果n=2,则:
(1)将A上的n-1(等于1)个圆盘移到B上;
(2)再将A上的一个圆盘移到C上;
(3)最后将B上的n-1(等于1)个圆盘移到C上。
如果n=3,则:
A)将A上的n-1(等于2,令其为n)个圆盘移到B(借助于C),步骤如下:
(1)将A上的n
-1(等于1)个圆盘移到C上。
(2)将A上的一个圆盘移到B。
(3)将C上的n-1(等于1)个圆盘移到B。
B)将A上的一个圆盘移到C。
C)将B上的n-1(等于2,令其为n
)个圆盘移到C(借助A),步骤如下:
(1)将B上的n-1(等于1)个圆盘移到A。
(2)将B上的一个盘子移到C。
(3)将A上的n
-1(等于1)个圆盘移到C。到此,完成了三个圆盘的移动过程。

总结
从上面分析可以看出,当n大于等于2时, 移动的过程可分解为三个步骤:第一步 把A上的n-1个圆盘移到B上;第二步 把A上的一个圆盘移到C上;第三步 把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。 当n=3时,第一步和第三步又分解为类同的三步,即把n’-1个圆盘从一个针移到另一个针上,这里的n`=n-1。

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