当前位置: 首页 > article >正文

算法:递归启蒙-汉诺塔

基本所有的讲递归的书和视频都会以汉诺塔作为开始,因为它足够经典

 

汉诺塔问题要求整个挪动的过程中都符合小压大的原则,就是如果同一个柱子上有超过1个的话,那必须下面是最大的,上面依次变小,不能出现大盘压小盘的情况。

n层汉诺塔问题解题思路

1.先把n-1个盘从左挪到中

2.把第n个盘从左挪到右

3.把1~n-1从中挪到右。

3层汉诺塔的具体步骤

 粗糙版代码:
 

package dataStructure.recurrence.practice;

public class Hanoi {
    public static void leftToRight(int n) {
        if(n == 1) {
            System.out.println("move 1 from left To Right");
            return;
        }
        leftToMiddle(n-1);
        System.out.println("move " + n + " from left to right");
        middleToRight(n - 1 );
    }

    public static void leftToMiddle(int n) {
        if(n == 1) {
            System.out.println("move 1 from left to middle");
            return;
        }
        leftToRight(n - 1);
        System.out.println("move " + n + " from left to middle");
        rightToMiddle(n - 1);

    }

    public static void middleToLeft(int n) {
        if(n == 1) {
            System.out.println("move 1 from middle to left");
            return;
        }
        middleToRight(n - 1);
        System.out.println("move " + n + " from middle to left");
        rightToLeft(n - 1);
    }

    public static void middleToRight(int n) {
        if(n == 1) {
            System.out.println("move 1 from middle to right");
            return;
        }
        middleToLeft(n -1 );
        System.out.println("move " + n + " from middle to right");
        leftToRight(n - 1);
    }

    public static void rightToLeft(int n) {
        if(n == 1) {
            System.out.println("move 1 from right to left");
            return;
        }
        rightToMiddle(n - 1 );
        System.out.println("move " + n + " from right to left");
        middleToLeft(n - 1);
    }

    public static void rightToMiddle(int n) {
        if(n == 1) {
            System.out.println("move 1 from right to middle");
            return;
        }
        rightToLeft(n - 1);
        System.out.println("move " + n + " from right to middle");
        leftToMiddle(n - 1);
    }

    public static void main(String[] args) {
        leftToRight(3);
    }
}

代码中枚举了6种可能性的移动,每个都写了一个方法,显然有些臃肿,我们可以通过增加参数来让方法拥有更多的功能。

改进后的正常版的汉诺塔代码

package dataStructure.recurrence.practice;

public class Hanoi2 {
    public static void move(int n, String from, String to, String other) {
        if(n == 1) {
            System.out.println("move 1 from " + from + " to " + to  );
        } else {
            move(n - 1, from, other, to);
            System.out.println("move " + n + " from " + from + " to " + to);
            move(n - 1, other, to, from);
        }
    }

    public static void main(String[] args) {
        move(3, "left", "right", "middle");
    }
}

运行结果:

move 1 from left to right
move 2 from left to middle
move 1 from right to middle
move 3 from left to right
move 1 from middle to left
move 2 from middle to right
move 1 from left to right

Process finished with exit code 0


http://www.kler.cn/a/17993.html

相关文章:

  • 前端-同源与跨域
  • 俏美韵从心出发,与女性一道为健康生活贡献力量
  • C/C++精品项目之图床共享云存储(3):网络缓冲区类和main
  • AcWing 302 任务安排 斜率优化的dp
  • 类别变量分析——卡方独立性检验卡方拟合优度检验
  • AtomicInteger 和 AtomicIntegerFieldUpdater的区别
  • ChatGPT使用入门
  • 计算机网络基础知识(一)计算机发展史、网络设备、网络结构及拓扑
  • 设计模式:SOLID原则
  • 2022级吉林大学面向对象第三次上机测试
  • 总结841
  • SSM框架学习-bean生命周期理解
  • new BroadcastChannel(),BroadcastChannel API使用介绍
  • 这就是实力~ 腾讯云大咖亲码 “redis深度笔记” 无废话全精华
  • 洗稿伪原创工具-洗稿生成器
  • SSM框架详解,实现高效优雅的Java Web开发
  • 【前端面经】CSS-浮动和清除浮动的方式
  • ePWM模块-时基模块(2)
  • Postgresql+Springboot yml基本使用
  • 通用操作日志处理方案
  • Vue如何使用富文本编辑器
  • PyTorch数据加载工具:高效处理常见数据集的利器
  • lombok常用的注解及使用方法
  • 实现前后端分离的登陆验证token思路
  • SpringBoot【开发实用篇】---- 配置高级
  • uniapp和小程序如何分包,详细步骤手把手(图解)