思路: 这里使用递归法

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程序的更多相关文章

  1. 数据结构--汉诺塔--借助栈实现非递归---Java

    /*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...

  2. C#递归解决汉诺塔问题(Hanoi)

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...

  3. python下实现汉诺塔

    汉诺塔是印度一个古老传说的益智玩具.汉诺塔的移动也可以看做是递归函数. 我们对柱子编号为a, b, c,将所有圆盘从a移到c可以描述为: 如果a只有一个圆盘,可以直接移动到c: 如果a有N个圆盘,可以 ...

  4. python实现汉诺塔移动

    汉诺塔问题 汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大 ...

  5. [algorithm] 汉诺塔问题

    汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗 ...

  6. #C++初学记录(初识汉诺塔)

    汉诺塔 题目 用1,2,...,n表示n个盘子,称为1号盘,2号盘,....号数大盘子就大.经典的汉诺塔问 题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于 印度传说的 ...

  7. K:汉诺塔问题

    相关介绍:  汉诺塔问题是一个通过隐式使用递归栈来进行实现的一个经典问题,该问题最早的发明人是法国数学家爱德华·卢卡斯.传说印度某间寺院有三根柱子,上串64个金盘.寺院里的僧侣依照一个古老的预言,以上 ...

  8. Python之汉诺塔递归运算

    汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆 ...

  9. P1047 汉诺塔

    题目描述 汉诺塔是根据一个印度传说形成的数学问题:有三根杆子A, B, C, A杆上有n个穿孔圆盘, 盘的尺寸由下到上依次变小. 要求按照下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘 大盘不能叠 ...

随机推荐

  1. Bayer Pattern——RGGB

    原博客地址:https://blog.csdn.net/joe9280/article/details/46952947 参考:https://blog.csdn.net/wgx571859177/a ...

  2. 题解 P3572 [POI2014]PTA-Little Bird

    P3572 [POI2014]PTA-Little Bird 首先,这道题的暴力dp非常好写 就是枚举所有能转移到他的点,如果当前枚举到的位置的值大于 当前位置的话,\(f[i]=min(f[i],f ...

  3. 一、Vuforia_AR

    一.AR概念: 增强现实(Augmented Reality,简称AR),是一种将虚拟信息与真实世界巧妙融合的技术,广泛运用了多媒体.三维建模.实时跟踪及注册.智能交互.传感等多种技术手段,将计算机生 ...

  4. java高级项目 jdbc与数据库连接数据库

    //图书管类 public class Book { private Integer id; private String b_name; private double b_price; privat ...

  5. golang拾遗:指针和接口

    这是本系列的第一篇文章,golang拾遗主要是用来记录一些遗忘了的.平时从没注意过的golang相关知识.想做本系列的契机其实是因为疫情闲着在家无聊,网上冲浪的时候发现了zhuihu上的go语言爱好者 ...

  6. Docker笔记4:在 CentOS 上安装 Docker

    Docker 是一个开源的应用容器引擎,主要有两个分支,一个是社区免费版(Docker CE),一个是企业版(Docker EE). 第1步:系统环境要求 Docker 支持的 CentOS 版本: ...

  7. Docker笔记2:Docker 镜像仓库

    Docker 镜像的官方仓库位于国外服务器上,在国内下载时比较慢,但是可以使用国内镜像市场的加速器(比如阿里云加速器)以提高拉取速度. Docker 官方的镜像市场,可以和 Gitlab 或 GitH ...

  8. html ul li 自定义宽

    1. ul里面的样式  2. ul li 里面的样式

  9. 使用css实现轮播图

    使用css3实现图片轮播 前言:实现图片轮播的方式有很多种 ,例如js ,css 等等. 本文主要讲述使用纯css3实现轮播图 工具介绍: 使用的编辑器: Hbuilder 进入正题 html代码: ...

  10. android init.rc语法

    转自:http://www.cnblogs.com/nokiaguy/p/3164799.html init.rc由如下4部分组成. 动作(Actions) 命令(Commands) 3. 服务(Se ...