汉诺塔问题java代码_汉诺塔java实现结果

汉诺塔问题java代码_汉诺塔java实现结果Java基础语法(汉罗塔)1起源2需求3分析3.11个碟子3.22个碟子3.33个碟子3.44个碟子3.5规律4代码实现:直接算法5代码实现封装:栈的思想1起源汉罗塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。2需求将汉罗塔问题抽象到数学:

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

1 起源

汉罗塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

2 需求

将汉罗塔问题抽象到数学:

  • 1.有三根杆子 A,B,C;
  • 2.A 杆上有若干大小不同的碟子,从上往下越来越大;
  • 3.每次移动一块碟子,小的只能叠在大的上面;
  • 4.把所有碟子从 A 杆全部移到 C 杆上。

在这里插入图片描述

3 分析

  • 确定 A 柱子上的初始碟子:int disks = 3;
  • 确定三个容器 char ‘A’、char ‘B’、char ‘C’;
  • 初始确定移动方法,从 from –> to:hanrotaMove(int disks, char from, char index, char to)。

3.1 1个碟子

A 柱子上只有一个碟子时,直接移动到 C:

num from index to mv
1 A B C A–>C

3.2 2个碟子

num from index to mv
1 A C B A–>B
2 A B C A–>C
1 B A C B–>C

3.3 3个碟子

num from index to mv
1 A B C A–>C
2 A C B A–>B
1 C A B C–>B
3 A B C A–>C
1 B C A B–>A
2 B A C B–>C
1 A B C A–>C

3.4 4个碟子

num from index to mv
1 A C B A–>B
2 A B C A–>C
1 B A C B–>C
3 A C B A–>B
1 C B A C–>A
2 C A B C–>B
1 A C B A–>B
4 A B C A–>C
1 B A C B–>C
2 B C A B–>A
1 C B A C–>A
3 B A C B–>C
1 A C B A–>B
2 A B C A–>C
1 B A C B–>C

3.5 规律

在上述前 4个下不难发现有规律存在:
A 柱子上有 n 个碟子,移动步骤便以 n 分为上下两部分,且上部分移动的数与下部分移动的数相同,此处便有递归分治的思想,解析 4 个碟子:
hanrotaMove(int disks, char from, char index, char to)
在初始入参:from ‘A’ – index ‘B’ – to ‘C’ 下,每一级都做为下一级分支的入参,且每个分支的上部都有相同的步骤“换”:from-to-index,每个分支的下部也都有相同的步骤“换”:index-from-to,可将此图看为完全二叉树。

4 代码实现:直接算法

代码常规实现:Hanrota.java

/** * @author zc * @date 2021/10/29 9:30 * 汉罗塔 * 1.有三根杆子 A,B,C; * 2.A 杆上有若干大小不同的碟子,从上往下越来越大; * 2.每次移动一块碟子,小的只能叠在大的上面; * 3.把所有碟子从 A 杆全部移到 C 杆上。 * * main(String[] args):主方法,主程序入口; * hanrotaMove(int disks, char from, char index, char to):方法,汉罗塔移动 */
public class Hanrota { 
   
    /** * 主程序入口 * @param args 系统参数 */
    public static void main(String[] args) { 
   
        // 初始化一个 A 柱子上碟子数
        int disks = 4;
        hanrotaMove(disks, 'A', 'B', 'C');
    }

    /** * 汉罗塔移动 * @param disks 待移动碟子数量 * @param from 起始点 * @param index 过渡点 * @param to 目标点 */
    public static void hanrotaMove(int disks, char from, char index, char to){ 
   
        if (disks <= 0){ 
   
            System.out.println("碟子数量不足");
        } else if (disks == 1) { 
   
            System.out.println("Disk " + disks + " from " + from + " to " + to);
        } else { 
   
            // 递归上部分
            hanrotaMove(disks - 1, from, to, index);
            // 中间分隔点
            System.out.println("Disk " + disks + " from " + from + " to " + to);
            // 递归下部分
            hanrotaMove(disks - 1, index, from, to);
        }
    }
}

运行结果:

Disk 1 from A to B
Disk 2 from A to C
Disk 1 from B to C
Disk 3 from A to B
Disk 1 from C to A
Disk 2 from C to B
Disk 1 from A to B
Disk 4 from A to C
Disk 1 from B to C
Disk 2 from B to A
Disk 1 from C to A
Disk 3 from B to C
Disk 1 from A to B
Disk 2 from A to C
Disk 1 from B to C

5 代码实现封装:栈的思想

汉罗塔的移动存储很像栈的思想:先进后出

就是在上一步的代码实现:直接算法上封装一下。

首先要 java 实现一个栈,再递归分治解决汉罗塔移动:MyStack.java

package com;

/** * @author zc * @date 2021/10/29 11:13 * 栈:MyStack * * main(String[] args):主方法,主程序入口 * MyStack(int s):有参构造,初始化栈容器的大小 * push(long j):方法,入栈 * pop():方法,出栈 * peek():方法,获取栈顶值 * isEmpty():方法,判断栈是否为空 * isFull():方法,判断栈是否存储满 * size():方法,获取当前栈中元数存储个数 * hanrotaMove(int disks, MyStack A, MyStack B, MyStack C):方法,汉罗塔移动 */
public class MyStack { 
   
    /** * 属性 maxSize:初始化栈的容器大小 */
    private int maxSize;
    /** * 属性 stackArray:栈中数据存储 */
    private long[] stackArray;
    /** * 属性 top:标志栈中最上一个元素值 */
    private int top;

    /** * 有参构造,初始化栈容器的大小 * @param s 栈容器大小 */
    public MyStack(int s) { 
   
        maxSize = s;
        stackArray = new long[maxSize];
        top = -1;
    }

    /** * 入栈 * @param j 入栈的元素 */
    public void push(long j) { 
   
        stackArray[++top] = j;
    }

    /** * 出栈 * @return 返回出栈的元素 */
    public long pop() { 
   
        return stackArray[top--];
    }

    /** * 获取栈中最上一个值 * @return 返回栈顶值 */
    public long peek() { 
   
        return stackArray[top];
    }

    /** * 判断栈是否为空 * @return 返回状态为空 true,否则 false */
    public boolean isEmpty() { 
   
        return (top == -1);
    }

    /** * 判断栈是否存储满 * @return 返回状态已满 true,否则 false */
    public boolean isFull() { 
   
        return (top == maxSize - 1);
    }

    /** * 求栈中当前存储元数个数 * @return 返回当前存储元数个数 */
    public int size(){ 
   
        return top + 1;
    }

    /** * 主程序入口 * @param args 系统参数 */
    public static void main(String[] args) { 
   
        // 初始化栈空间
        int topN = 3;
        // 初始化 A 栈空间
        MyStack A = new MyStack(topN);
        // 初始化 B 栈空间
        MyStack B = new MyStack(topN);
        // 初始化 C 栈空间
        MyStack C = new MyStack(topN);

        // 给 A 栈添加汉罗塔数
        A.push(13);
        A.push(9);
        A.push(4);

        // 汉罗塔移动
        hanrotaMove(A.size(),A,B,C);

        // 打印 C 栈元素
        while (!C.isEmpty()){ 
   
            System.out.print(C.pop() + " ");
        }

    }

    /** * 汉罗塔移动 * @param A A 柱子 * @param B B 柱子 * @param C C 柱子 */
    public static void hanrotaMove(int disks, MyStack A, MyStack B, MyStack C){ 
   
        if (disks <= 0){ 
   
            System.out.println("A 柱子上没有数据");
        } else if (disks == 1) { 
   
            // A 中出栈
            long value = A.pop();
            System.out.println("Disk " + value + " from " + A + " to " + C);
            // C 中入栈
            C.push(value);
        } else { 
   
            // 递归上部
            hanrotaMove(disks - 1, A, C, B);
            // A 中出栈
            long value = A.pop();
            System.out.println("Disk " + value + " from " + A + " to " + C);
            // C 中入栈
            C.push(value);
            // 递归下部
            hanrotaMove(disks - 1, B, A, C);
        }
    }
}

运行结果:

Disk 4 from com.MyStack@74a14482 to com.MyStack@1540e19d
Disk 9 from com.MyStack@74a14482 to com.MyStack@677327b6
Disk 4 from com.MyStack@1540e19d to com.MyStack@677327b6
Disk 13 from com.MyStack@74a14482 to com.MyStack@1540e19d
Disk 4 from com.MyStack@677327b6 to com.MyStack@74a14482
Disk 9 from com.MyStack@677327b6 to com.MyStack@1540e19d
Disk 4 from com.MyStack@74a14482 to com.MyStack@1540e19d
4 9 13 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/182972.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 3D点云实例分割_3d点云标注软件

    3D点云实例分割_3d点云标注软件3D点云实例分割3D语义分割区分场景中各类对象,3D实例分割区分场景中各类别中的各种个体。近两年来,3D实例分割的关注度越来越高,相应的方法也被接连提出。众多方法的思想主要分为两类:基于候选区域的实例分割(proposal-based)和免候选区域的实例分割(proposal-free)。其中,proposal-based先获取场景中的感兴趣的候选区域,如:3Dboundingboxes等…

    2022年8月23日
    13
  • APP测试工具大全,建议收藏「建议收藏」

    APP测试工具大全(建议收藏!!!)一、APP自动化测试工具AppiumAirtestuiautomator2(python)二、APP稳定性测试工具MonkeyMonkeyRunnerMaximUICrawler三、APP性能测试工具GTPerfdogSoloPi四、APP弱网测试&抓包工具QNETFiddlerCharles五、APP兼容性测试工具TestIn腾讯优测百度MTC阿里MQC六、APP安全测试工具OWASPZA.

    2022年4月16日
    38
  • datax(3): win环境cmd乱码「建议收藏」

    datax(3): win环境cmd乱码「建议收藏」通过前面两篇文章,大家应该已经可以安装成功datax,但是在win的cmd下竟然中文乱码。解决它!!!一,环境win10datax3.xcmdpy3.x二,现象运行python\xxx\datax.py\xxx\job.json后控制台乱码三,解决1,临时解决命令:chcp(更改该控制台的活动控制台代码页)过程:cmd下输入chcp65001改变当前代码页变为utf-8编码常用的编码及对应的码值(10进制):十进制码值 对应编码名称950 .

    2022年5月13日
    101
  • Maven下载安装

    Maven下载安装

    2021年7月20日
    69
  • url的加密解密_url地址加密

    url的加密解密_url地址加密今天做项目构造链接参数的时候,推送到app上的链接点了没办法跳转到对应的界面对比了一下能跳转的链接,原来是url没有加密,就推送过去了在这里把对url加密解密的方法记录一下,方便以后使用publicstaticStringgetURLEncoderString(Stringstr){Stringresult="";if(null==str){…

    2025年7月2日
    5
  • plantuml 依赖_遇见PlantUML

    plantuml 依赖_遇见PlantUML前言来到公司实习也快一个月了,最大的体会就是,虽然大部分时间做的是简单的增删该查,但不同于在学校时写的Demo,你要充分考虑程序的鲁棒性(健壮性)、可扩展性(可维护性)、时间/空间复杂度等。因为是要实际上线的项目,你需要面面俱到,对团队负责。于是决定在完成组里任务之余,花时间提高自己的的编码规范、多思考程序设计的可扩展性、性能是否可观等。我觉得开发工程师和码农之间的区别是,不仅是复制粘贴和以实现功…

    2025年6月23日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号