Java基于栈方式解决汉诺塔问题实例【递归与非递归算法】

Java基于栈方式解决汉诺塔问题实例【递归与非递归算法】

算法介绍

汉诺塔问题是经典的递归算法示例。简单来说,汉诺塔问题是将一堆盘子从源柱子移动到目标柱子,可以借助第三个柱子,且每次只能移动一个较小的盘子到目标柱子上。其中,要求大的盘子必须在小的盘子之下。

为了解决汉诺塔问题,我们需要使用递归算法或非递归算法。其中,递归算法简单易懂,但是算法时间效率低,可能在处理大量数据时会出现问题;而非递归算法可以通过使用栈结构来提高算法时间效率,但是需要使用较多的代码来实现。

递归算法实现

递归算法实现汉诺塔问题很简单,只需要限定盘子的规模,然后将规模递减进行递归即可。

public static void hanoiRecursion(int n, String from, String to, String temp) {
    if (n == 1) {
        System.out.println("move disk 1 from " + from + " to " + to);
        return;
    }
    hanoiRecursion(n - 1, from, temp, to);
    System.out.println("move disk " + n + " from " + from + " to " + to);
    hanoiRecursion(n - 1, temp, to, from);
}

在上述代码中,我们首先判断盘子的规模是否为1,如果是1,则直接将盘子从源柱子移动到目标柱子上;否则,我们需要将大于1的盘子先移动到借助柱子上,然后再将最后一个盘子直接从源柱子移动到目标柱子上。

非递归算法实现

非递归算法实现汉诺塔问题需要借助栈的结构来保存每一步的状态,然后通过出栈入栈等操作来模拟递归过程。具体实现如下:

public static void hanoiLoop(int n, String from, String to, String temp) {
    Stack<Hanoi> stack = new Stack<Hanoi>();
    Hanoi hanoi = new Hanoi(n, from, to, temp);
    int count = 1;
    while (true) {
        while(hanoi != null && hanoi.n > 1) {
            Hanoi hanoiTemp = new Hanoi(hanoi.n - 1, hanoi.temp, hanoi.to, hanoi.from);
            stack.push(hanoi);
            stack.push(hanoiTemp);
            hanoi = hanoiTemp;
            count ++;
        }
        if(hanoi != null) {
            System.out.println("move disk " + hanoi.n + " from " + hanoi.from + " to " + hanoi.to);
        }
        if (stack.isEmpty())
            break;
        hanoi = stack.pop();
    }
    System.out.println("Total steps: " + count);
}

static class Hanoi {
    int n;
    String from;
    String to;
    String temp;
    public Hanoi(int n, String from, String to, String temp) {
            this.n = n;
            this.from = from;
            this.to = to;
            this.temp = temp;
    }
}

在上述代码中,我们首先创建一个栈结构,然后将初始状态压入栈底。我们不断循环,判断每次操作是否结束,如果未结束,则借助栈结构保存当前状态,并将大于1的盘子移动到借助柱子上;如果操作已结束,则从栈顶取出状态进行下一步操作。直到栈为空,整个算法结束。

示例说明

在上述两种算法中,我们分别使用递归和非递归算法来实现汉诺塔问题。如果我们要将三个盘子从A柱子移动到C柱子,可以调用以上两个方法并输出结果:

System.out.println("递归算法:");
hanoiRecursion(3, "A", "C", "B");

System.out.println("非递归算法:");
hanoiLoop(3, "A", "C", "B");

输出结果如下:

递归算法:
move disk 1 from A to C
move disk 2 from A to B
move disk 1 from C to B
move disk 3 from A to C
move disk 1 from B to A
move disk 2 from B to C
move disk 1 from A to C

非递归算法:
move disk 1 from A to C
move disk 2 from A to B
move disk 1 from C to B
move disk 3 from A to C
move disk 1 from B to A
move disk 2 from B to C
move disk 1 from A to C
Total steps: 13

从结果中可以看出,递归算法和非递归算法均可以正确解决汉诺塔问题,且输出结果一致。但是非递归算法需要花费更少的计算时间来完成同样的任务。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java基于栈方式解决汉诺塔问题实例【递归与非递归算法】 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 解析Java继承中方法的覆盖和重载

    下面是详细讲解“解析Java继承中方法的覆盖和重载”的完整攻略。 什么是Java继承? Java继承是一种面向对象编程的重要概念。在Java中,子类可以从父类继承属性和方法,从而减少代码的重复,提高代码的复用性。子类也可以新增自己特有的属性和方法。通过继承,子类可以使用父类的方法和属性,同时也可以根据自身需要进行扩展和修改。在Java中,子类可以覆盖或重载父…

    other 2023年6月27日
    00
  • 浅谈Python中的私有变量

    浅谈Python中的私有变量 在Python中,私有变量是指以双下划线(__)开头的变量。私有变量的存在意味着它们只能在类的内部访问,无法在类的外部直接访问。私有变量的使用可以帮助我们封装类的内部实现细节,提高代码的安全性和可维护性。 定义私有变量 要定义一个私有变量,只需在变量名前加上双下划线(__)。例如: class MyClass: def __in…

    other 2023年8月9日
    00
  • 简单了解spring bean的循环引用

    简单了解spring bean的循环引用 在Spring中,循环依赖是指两个或多个bean彼此依赖,导致无法完成依赖注入的情况。循环依赖可能会导致程序出错,因此要了解循环依赖产生的原因和解决方法。 循环引用的原因 Spring在初始化bean时,会自动处理它们之间的依赖关系。当两个或多个bean相互依赖,即出现循环依赖时,Spring无法完成依赖注入,从而循…

    other 2023年6月27日
    00
  • Android App中实现图片异步加载的实例分享

    Android App中实现图片异步加载的实例分享 在Android应用程序中,实现图片异步加载是一种常见的需求。这可以提高应用程序的性能和用户体验,避免在加载大量图片时出现卡顿现象。下面是一个完整的攻略,包含了两个示例说明。 示例1:使用Picasso库进行图片异步加载 首先,确保在项目的build.gradle文件中添加Picasso库的依赖项: dep…

    other 2023年9月7日
    00
  • WiFi万能钥匙在哪查看版本号?WiFi万能钥匙查看版本号教程

    WiFi万能钥匙版本号查看攻略 WiFi万能钥匙是一款常用的无线网络连接工具,它提供了方便的WiFi连接服务。如果你想查看WiFi万能钥匙的版本号,可以按照以下步骤进行操作: 打开WiFi万能钥匙应用:在你的手机上找到并点击WiFi万能钥匙应用的图标,以打开应用。 进入设置界面:在WiFi万能钥匙的主界面上,通常会有一个设置图标,一般是一个齿轮状的图标。点击…

    other 2023年8月3日
    00
  • 详解Angular组件生命周期(一)

    Angular组件生命周期是指一个组件从创建到销毁的整个生命周期,包含了多个钩子函数,可以在不同的组件生命周期阶段执行不同的操作,让我们更好地控制组件的行为。本文将详细讲解Angular组件生命周期的一部分,包括OnInit、OnChanges、DoCheck等常用的钩子函数。 OnInit OnInit是一个当Angular组件初始化时会自动执行的钩子函数…

    other 2023年6月27日
    00
  • 小米云服务Windows版客户端正式发布:可远程控制手机

    小米云服务Windows版客户端正式发布:可远程控制手机 小米云服务发布了Windows版客户端,用于远程控制手机、传输文件及备份手机数据等功能。本文将详细讲解该客户端的使用攻略。 下载安装 在小米云服务客户端下载页面,选择相应的操作系统版本(Windows 7/8/10),单击下载按钮。 示例: 1. 打开小米云服务官方网站,进入“小米云服务客户端下载”页…

    other 2023年6月25日
    00
  • 利用PHP和百度ai实现文本以及图片的审核

    利用PHP和百度AI实现文本以及图片的审核 在很多网站应用中,我们可能需要对用户上传的文本和图片进行审核,以保证其内容不含有不良信息,不违反法律法规,同时也保护其他用户的利益。本文将介绍如何利用PHP和百度AI实现文本和图片审核的功能。 百度AI平台介绍 百度AI(Baidu AI)平台是由百度推出的人工智能开发平台,涵盖了图像识别、语音识别、自然语言处理等…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部