汉诺塔问题及可视化操作

汉诺塔可视化

作为一个小白,深知算法的枯燥.但是,算法是要学习的。今天给大家提供一个好一点的学习方法。算法的可视化,让大家找到算法的兴趣。 就用Graphics2D这个类,操作很简单,没什么技术,但是和算法结合到一起,就很有趣了。会让你看到了算法的可视化操作,同样也感受到了算法的魅力,也许在以后的算法学习中,用可视化为你开启一段不一样的初学之路,也算是比较有趣的东西。
今天我们就来聊一聊汉诺塔。汉诺塔可算是一个递归的典例。首先我们来看一看未可视化汉诺塔代码。

public class Hello{
    static void fun(int n,char A,char B,char C){
        if(n==1) {			//跳出条件
            System.out.println(A + "--" + C);
            return;
        }
        fun(n - 1, A, C, B);    //A通过C盘辅助放到B盘上
        System.out.println(A + "--" + C);
        fun(n - 1, B, A, C);   //B通过A盘辅助放到C盘上
    }
    public static void main(String[] args) {
        fun(3,'A','B','C');
    }
}
  可能学习汉诺塔乃至编程算法比较枯燥,看着上面的代码,不容易看懂,递归的解题思路大部分都是在纸上进行的,简单的代码中蕴含着慢慢的智慧。
解析:  老板分任务
   老板思维:我干一点,剩下的交给下面的人做
   老板:我要做的就是将最后一个盘子移到C盘上
          1. 前n-1个盘子移到B盘上 (交给小弟做的)    fun(n - 1, A, C, B);
          2. 将最后一个盘子移到C上   System.out.println(A + "--" + C);
          3. 然后再将B上的盘子移到C上(也是交给小弟做的)   fun(n - 1, B, A, C);
          
 可视化操作:

以下为简单代码,可改进
CanVisableJFrame类 extends JFrame
创建 窗体
(以下程序创于同一包内)

//视图层
import javax.swing.*;
import java.awt.*;
public class CanVisableJFrame extends JFrame {
    static int i=0;
    int block=50;
   int Hanoi1[];    //容器A
    int Hanoi2[];	//容器B
    int Hanoi3[];   //容器C
    int number;
    CanVisableJFrame(int Hanoi1[],int Hanoi2[],int Hanoi3[]){ //初始化操作
        this.Hanoi1=Hanoi1;
        this.Hanoi2=Hanoi2;
        this.Hanoi3=Hanoi3;
        this.number=number;
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭方式,点击直接x退出程序,不用强制退出(推荐)
       setVisible(true);    //是否可见(必备,否则不显示窗体、画布)
        setBackground(Color.LIGHT_GRAY); //设置窗体背景颜色
       setBounds(100,50,1200,650);		//设置窗体大小
        HanoiJPanel hanoiJPanel=new HanoiJPanel(); //创建画布,在画布上画图形,窗体上不能画图形,必须添加画布,此画布继承Jpanl
        setContentPane(hanoiJPanel);   //在窗体上添加显示画布
        hanoiJPanel.setBounds(100,50,1200,650); //设置画布尺寸
        hanoiJPanel.setBackground(Color.lightGray);//设置画布背景颜色
        HanoiMoble hanoiMoble=new HanoiMoble(Hanoi1,Hanoi2,Hanoi3);//添加动作
        hanoiMoble.fun(6,'A','B','C');  //添加数据层、逻辑层
        for(int i=0;i<Math.pow(2,7)-1;i+=2){//
        hanoiMoble.UpData(Hanoi1,Hanoi2,Hanoi3,i);
            repaint(); //JFrame中方法,刷新作用
            try {
                Thread.sleep(800);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        }

import java.util.ArrayList;
import java.util.Stack;

public class HanoiMoble {
    ArrayList<Character> list=new ArrayList<>();
    int Hanoi1[];
    int Hanoi2[];
    int Hanoi3[];
    HanoiMoble(int Hanoi1[],int Hanoi2[],int Hanoi3[]) {
        this.Hanoi1=Hanoi1;
        this.Hanoi2=Hanoi2;
        this.Hanoi3=Hanoi3;
    void fun(int n,char A,char B,char C){   //list中存入数据
        if(n==1) {
            list.add(A);
            list.add(C);
            return;
        }
        fun(n - 1, A, C, B);
        list.add(A);
        list.add(C);
        fun(n - 1, B, A, C);
    }
    int index1=5;int index2=-1;int index3=-1;
    void UpData(int Hanoi1[],int Hanoi2[],int Hanoi3[],int i){            //数据的更新
            if(list.get(i)=='A'){
                if(list.get(i+1)=='B') {        //1--2
                    Hanoi2[++index2] = Hanoi1[index1];
                    Hanoi1[index1]=0;
                    index1--;
                }
                else    {                          //1-3
                    Hanoi3[++index3]=Hanoi1[index1];
                    Hanoi1[index1]=0;
                    index1--;
                }
            }
            if(list.get(i)=='B'){
                if(list.get(i+1)=='A') {        //2--1
                    Hanoi1[++index1] = Hanoi2[index2];
                    Hanoi2[index2]=0;
                    index2--;
                }
                else    {                          //2-3
                    Hanoi3[++index3]=Hanoi2[index2];
                    Hanoi2[index2]=0;
                    index2--;
                }
            }
            if(list.get(i)=='C'){
                if(list.get(i+1)=='A') {        //3--1
                    Hanoi1[++index1] = Hanoi3[index3];
                    Hanoi3[index3]=0;
                    index3--;
                }
                else    {                          //3-2
                    Hanoi2[++index2]=Hanoi3[index3];
                    Hanoi3[index3]=0;
                    index3--;
                }
            }

    }
}

工具类

import java.awt.*;
class StaticMethod {//工具类 画方格
static void VirtualHanoi(int Hanoi1[],int Hanoi2[],int Hanoi3[], Graphics2D g2){
    int a1=0;int b1=0;int c1=0;int h1=0;int h2=0;int h3=0;
    for(int i=0;i<Hanoi1.length;i++) {
        g2.fill3DRect(200 - Hanoi1[i] / 2, 530 - h1, Hanoi1[i],50, false);//矩形方格绘制
        h1+=50;
    }
    for(int i=0;i<Hanoi2.length;i++) {
        g2.fill3DRect(625 - Hanoi2[i] / 2, 530 - h2, Hanoi2[i],50, false);
        h2+=50;
    }
    for(int i=0;i<Hanoi3.length;i++) {
        g2.fill3DRect(1000 - Hanoi3[i] / 2, 530 - h3, Hanoi3[i],50, false);
        h3+=50;
    }
}
}

主类


public class Hello {//主类
    static int i=0;
    public static void main(String[] args) {

        int CavesWith = 1150;           //画谱的宽
        int CavesHeight = 650;          //画布的长
        int HanoiGap = 50;             //汉诺塔之间的间隔
        int RightGap=75;                //汉诺塔左边缘
        int HanoiWith=300;              //汉诺塔塔底最大宽度
        int EveryGap=25;                   //汉诺塔没两个之间差距的一半
        int Hanoi1[]={300,250,200,150,100,50};//汉诺塔的底数组
        int Hanoi2[]={0,0,0,0,0,0};       //当为零时,可视化时是一根柱子
        int Hanoi3[]={0,0,0,0,0,0};
        CanVisableJFrame frame = new CanVisableJFrame(Hanoi1,Hanoi2,Hanoi3);//调用窗体,程序开始
        }
        }

效果图
汉诺塔问题及可视化操作_第1张图片

汉诺塔视频链接-点击查看

链接转向土豆视频
汉诺塔问题及可视化操作_第2张图片

以上为全部代码,但只是很简单的代码,感觉可以用栈、队列等数据结构,但会报错,望大神指点,自己可以优化。可能比较繁琐,望大神莫喷。有问题互相交流。

你可能感兴趣的:(算法)