汉诺塔问题实验--一个简洁的JAVA程序
思路: 这里使用递归法
n==1的时候,直接把它从x移到z位置即可。
如果是n层,我们首先把上面的n- 1层移到y位置,然后把最 下面的那个最大的盘子,移到z位置,然后把y上面放的上面n-1层移到z位置即即可,
我们在移动上面n-1层盘子的时候。先把上面n-2层移到z位置,然后把第n- 1层那个最大的放到y位置,然后把z上面的n-2层移到y位置即可。
我们在移动上面n-2层盘子的时候,先把上面n- 3层移到y位置,然后把最大的那个第n- 2层移到z位置,然后把y上面放的n- 3层放到z位置即可。
我们在移动上面n-3层盘子的时候,........... .递归就完事了!
我们在移动上面2层盘子的时候,首先把上面那个放到y(z)上面,然后把第二层放到z(y)上面,再把y(z) 上面的那一层移到z(y)上面即可。我们在移动上面那一层的时候,n==1
由递推方程的知识可知,该过程的时间复杂性为O(2^n),64层就要移动2^64-1次盘子。不过这次我们使用程序观察这个变化
这个程序记录了1到36个盘子的时候,Hanoi tower的移动次数,执行时间。为了保证效率,不打印中间结果,只打印最终结果
public class Hanoi {
/**
* author:ZhaoKe
* college: CUST
*/
public long count = 0;
public void hanoi(int n,char a,char b,char c) {
//Hanoi塔问题其实就这几行
if (n == 1) {
this.count++;
}else {
this.hanoi(n-1, a, c, b);
this.count++;
this.hanoi(n-1, b, a, c);
}
}
public static void main(String[] args) {
//程序看起来挺长,大部分代码都是为计算时间服务的
Hanoi ha = new Hanoi();
long begin = System.currentTimeMillis(); //获得当前系统时间
long end = begin; //循环之前,这里end作为上一轮循环的结束时间,虽然循环还没开始
for (int i = 1; i <= 36; i++) {
ha.count = 0; //循环开始,执行次数置0
begin = end; //循环开始,起始时间是上一轮循环的结束时间
ha.hanoi(i, 'a', 'b', 'c'); //其实Hanoi塔问题只要这一句就够了,其他语句都是为了计算运行时间
end = System.currentTimeMillis(); //程序结束时间
System.out.println(i+"个盘子,一共有" +ha.count+ "步");
System.out.println("程序运行时间:" + (end - begin) + " ms"); //程序运行时间,单位毫秒ms
}
}
}
运行结果是怎样的呢?
前面盘子比较少的时候就省略了,运行时间都小于1ms,程序显示基本为0ms。
程序运行时间:14 ms
24个盘子,一共有16777215步
程序运行时间:15 ms
25个盘子,一共有33554431步
程序运行时间:66 ms
26个盘子,一共有67108863步
程序运行时间:68 ms
27个盘子,一共有134217727步
程序运行时间:238 ms
28个盘子,一共有268435455步
程序运行时间:239 ms
29个盘子,一共有536870911步
程序运行时间:914 ms
30个盘子,一共有1073741823步
程序运行时间:973 ms
31个盘子,一共有2147483647步
程序运行时间:3681 ms
32个盘子,一共有4294967295步
程序运行时间:3887 ms
33个盘子,一共有8589934591步
程序运行时间:14602 ms
34个盘子,一共有17179869183步
程序运行时间:15504 ms
35个盘子,一共有34359738367步
程序运行时间:58773 ms
36个盘子,一共有68719476735步
程序运行时间:61197 ms
可见十分恐怖了。
对照一下打印中间结果多么消耗性能,这里只打印最终结果:

如果将执行的每一步都打印出来的话(使用System.out.println(".........")),n=26的时候就使用了427009ms,比如

汉诺塔问题实验--一个简洁的JAVA程序的更多相关文章
- 数据结构--汉诺塔--借助栈实现非递归---Java
/*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...
- C#递归解决汉诺塔问题(Hanoi)
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...
- python下实现汉诺塔
汉诺塔是印度一个古老传说的益智玩具.汉诺塔的移动也可以看做是递归函数. 我们对柱子编号为a, b, c,将所有圆盘从a移到c可以描述为: 如果a只有一个圆盘,可以直接移动到c: 如果a有N个圆盘,可以 ...
- python实现汉诺塔移动
汉诺塔问题 汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大 ...
- [algorithm] 汉诺塔问题
汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗 ...
- #C++初学记录(初识汉诺塔)
汉诺塔 题目 用1,2,...,n表示n个盘子,称为1号盘,2号盘,....号数大盘子就大.经典的汉诺塔问 题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于 印度传说的 ...
- K:汉诺塔问题
相关介绍: 汉诺塔问题是一个通过隐式使用递归栈来进行实现的一个经典问题,该问题最早的发明人是法国数学家爱德华·卢卡斯.传说印度某间寺院有三根柱子,上串64个金盘.寺院里的僧侣依照一个古老的预言,以上 ...
- Python之汉诺塔递归运算
汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆 ...
- P1047 汉诺塔
题目描述 汉诺塔是根据一个印度传说形成的数学问题:有三根杆子A, B, C, A杆上有n个穿孔圆盘, 盘的尺寸由下到上依次变小. 要求按照下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘 大盘不能叠 ...
随机推荐
- python中的filter、map、reduce、apply用法总结
1. filter 功能: filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数. 调用: filter(function,seq ...
- mycat 1.6实现读写分离
使用mysql的root账号执行mysql>grant all privileges on *.* to mycatuser@% identified by '123456';mysql> ...
- mycat 单库分表实践
参考 https://blog.csdn.net/sq2006hjp/article/details/78732227 Mycat采用的水平拆分,不管是分库还是分表,都是水平拆分的.分库是指,把一个大 ...
- 搭建ipse隧道
我没有太多的物理服务器,实验环境只能用四台装了linux的虚拟机来模拟,用户层工具是openswan.大致拓扑如下(我有点懒,公网地址我用的194.168.10.0/24,别和192.168.xx.x ...
- 1-JAVA类、接口、抽象、多态
类中全部成员变量用priviate修饰,用get获取,set设值 对于boolean类型的值,getter方法也一定要写成isXXX 的形式,而setXXX类型不变 this关键字的作用 当方法的局部 ...
- Android开发签名证书的生成
现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕!我这边专门针对Android开发工程师整理了一套[Android进阶学习视频].[全套Android面试秘籍].[Android知识点PDF] ...
- swoole协程通道channel
swoole 协程通道 为了协程直接互相通讯传递数据 和go的通道很相似 Co\run(function(){ $chan = new Swoole\Coroutine\Channel(1); Swo ...
- go 协程阻塞
func main() { wg.Add(2) go test1() go test2() wg.Wait() } func test1() { defer wg.Done() for i:=0;i& ...
- php生成器 yield 转
一.yield介绍 文档介绍说道:生成器函数的核心是yield关键字.它最简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给 ...
- selenium基础--五种定位方式
find_element_by_name find_element_by_id find_element_by_xpath find_element_by_link_text find_element ...