算法详解--汉诺塔

    xiaoxiao2021-03-25  139

    算法由来 小故事 汉诺塔(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。

    好一个大布丁 认证博客专家 Java Redis 分布式 手游服务器研发工程师。有参与射击类型手游《雷霆战机》。MMO《末日危机》,SLG+ARPG《末日生存》开发经验。现在主要研究全球游戏服务器SLG类型游戏开发。研究分布式和微服务在游戏服务器中的应用。
    转载请注明原文地址: https://ju.6miu.com/read-9435.html

    最新回复(0)