【算法】递归法实现汉诺塔问题

本文介绍了一个汉诺塔问题的变体,其中盘子不能直接从'左'移动到'右',必须经过'中'。通过递归方法详细阐述了解决方案,包括相邻柱子和不相邻柱子的移动策略,并提供了测试程序及其结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归法实现汉诺塔问题

这里的汉诺塔问题稍加改动:从“左”不能直接到“右”,必须先从“左”到“中”,再从“中”到“右”;从“右”到“左”同理;即只能在相邻的柱子间移动。

思路:

  • process(int num, String from, String to)函数,实现了第num块,从from柱子到to柱子的移动过程
  • 移动分为两类,相邻柱子的移动,不相邻柱子的移动(如果是传统的汉诺塔问题则不用如此分类)
  • 相邻柱子的移动:从"左"到"中"从"右"到"中"从"中"到"左"从"中"到"右"
      1. 上面的num - 1层,从from移到另一个柱子,即除了fromto的另一根柱子
      1. 然后第num块从fromto
      1. 上面的num - 1层从另一个柱子到to
  • 不相邻柱子的移动:从"左"到"右"从"右"到"左"
      1. 上面的num - 1层从fromto
      1. num块,从from移到middle
      1. 然后第num - 1块从tofrom
      1. num块,从middle移到to
      1. 上面的num - 1层从fromto
package com.lilydedbb;

/**
 * Created by dbb on 2016/12/24.
 */
public class HanoiProblemByRecursion {

    private static String left = "left  ";
    private static String mid = "middle";
    private static String right = "right ";

    public static int hanoiProblem(int num){
        if (num < 1)
            return 0;
        return process(num, left, right);
    }

    // 返回的是步数
    public static int process(int num, String from, String to){

        // 只有一个的时候
        if(num == 1){
            if(from.equals(mid) || to.equals(mid)){
                System.out.println("move 1 from " + from + " to " + to);
                return 1;
            }else{
                System.out.println("move 1 from " + from + " to middle");
                System.out.println("move 1 from middle to " + to);
                return 2;
            }
        }

        // 从"左"到"中",从"右"到"中",从"中"到"左",从"中"到"右"
        if(from.equals(mid) || to.equals(mid)){
            String another = (from.equals(left) || to.equals(left)) ? right : left;
            int part1 = process(num - 1, from, another);
            int part2 = 1;
            System.out.println("move " + num + " from " + from + " to " + to);
            int part3 = process(num - 1, another, to);
            return part1 + part2 + part3;
        } else { // 从"左"到"右",从"右"到"左"
            int part1 = process(num - 1, from, to);
            int part2 = 1;
            System.out.println("move " + num + " from " + from + " to middle");
            int part3 = process(num - 1, to, from);
            int part4 = 1;
            System.out.println("move " + num + " from middle to " + to);
            int part5 = process(num - 1, from, to);
            return part1 + part2 + part3 + part4 + part5;
        }
    }

}

测试程序及测试结果如下:

int steps = HanoiProblemByRecursion.hanoiProblem(2);
System.out.println("The Minimum step is " + steps);
move 1 from left   to middle
move 1 from middle to right 
move 2 from left   to middle
move 1 from right  to middle
move 1 from middle to left  
move 2 from middle to right 
move 1 from left   to middle
move 1 from middle to right 
The Minimum step is 8

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值