用递归算法实现汉诺塔问题。

用递归算法实现汉诺塔问题。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Scanner;

public class HanoiTower {

    //三个数组列表分别表示三根柱子,count表示调换次数,numberOfDisks表示盘子总数
    private ArrayList<Integer> A = new ArrayList<>();
    private ArrayList<Integer> B = new ArrayList<>();
    private ArrayList<Integer> C = new ArrayList<>();
    private PrintWriter output;
    private int count = 0;
    private int numberOfDisks =0;

    public static void main(String[] args) throws FileNotFoundException{
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入盘子数量:");
        int i=scanner.nextInt();
        //调用函数
        new HanoiTower(i).moveDisks();
    }
    public HanoiTower(int n) throws FileNotFoundException {
        this.numberOfDisks = n;
        //在当前目录新建HanoiTower_n.txt用于存储调换过程
        //这里建议你重新编写生成文件路径
        this.output = new PrintWriter(new File("HanoiTower_"+n+".txt"));
        //初始化柱子
        for(int i=n;i>0;i--) {
            this.A.add(i);
        }
        //把初始状态存入文件
        this.output.println("总盘子数目:"+n);
        this.output.println("---------初始状态---------");
        this.output.print("A: ");
        for(Integer i:this.A) this.output.print(i+" ");
        this.output.println();
        this.output.print("B: ");
        for(Integer i:this.B) this.output.print(i+" ");
        this.output.println();
        this.output.print("C: ");
        for(Integer i:this.C) this.output.print(i+" ");
        this.output.println();
    }
    public void moveDisks() {
        this.moveDisks(this.numberOfDisks,this.A,this.B,this.C);
        this.output.close();
        System.out.println("已完成调换");
    }

    public void moveDisks(int n, ArrayList<Integer> fromTower, ArrayList<Integer> toTower, ArrayList<Integer> auxTower) {
        if(n == 1) {
            //当需要移动的盘子只有1个时,可以直接进行移动,而不需要递归
            move(fromTower,toTower);

            //每一次调换均输出当前A、B、C柱的情况到文件中做记录
            this.output.println("--------第"+(++this.count)+"次调换--------");
            this.output.print("A: ");
            for(Integer i:this.A) this.output.print(i+" ");
            this.output.println();
            this.output.print("B: ");
            for(Integer i:this.B) this.output.print(i+" ");
            this.output.println();
            this.output.print("C: ");
            for(Integer i:this.C) this.output.print(i+" ");
            this.output.println();
            System.out.println("已完成第"+this.count+"次调换");

        }
        else {
            //把上面(n-1)个盘子当做一个整体,从fromTower移动到auxTower
            moveDisks(n-1,fromTower,auxTower,toTower);
            //把fromTower仅剩下的最大半径的盘子移动到toTower(即只有一个盘子需要移动的情况)
            moveDisks(1,fromTower,toTower,auxTower);
            //把刚刚移动到C柱的(n-1)个盘子作为整体从auxTower移动到toTower
            moveDisks(n-1,auxTower,toTower,fromTower);
        }

    }

    public static void move(ArrayList<Integer> fromTower, ArrayList<Integer> toTower) {
        //fromTower最大索引元素(即柱子最上面的盘子)的值添加到toTower,然后把这个元素从fromTower删除,
        //通过这两步模拟盘子的移动
        toTower.add(fromTower.get(fromTower.size()-1));
        fromTower.remove(fromTower.size()-1);

    }


}

运行结果
在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值