汉诺塔

 

一、汉诺塔递归实现

public class Hanio {

    private static final String LIST_A = "A";
    private static final String LIST_B = "B";
    private static final String LIST_C = "C";

    public static void main(String[] args) {
        long starTime = System.currentTimeMillis();
        new Hanio().init(20);
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - starTime);
    }

    Map<String, List<Integer>> map;

    public void init(int n) {
        map = new HashMap<>();
        List<Integer> listA = new ArrayList<>();
        map.put(LIST_A, listA);
        map.put(LIST_B, new ArrayList<>());
        map.put(LIST_C, new ArrayList<>());
        for (int i = n; i > 0; i--) {
            listA.add(i);
        }
        pringMap();
        move(n, LIST_A, LIST_B, LIST_C, map);
    }


    public void move(int n, String a, String b, String c, Map<String, List<Integer>> map) {
        if (n == 1) {
            action(a, c);
        } else {
            move(n - 1, a, c, b, map);
            move(1, a, b, c, map);
            move(n - 1, b, a, c, map);
        }
    }

    private void action(String from, String to) {
        List<Integer> listFrom = map.get(from);
        List<Integer> listTo = map.get(to);
        Integer target = listFrom.get(listFrom.size() - 1);
        listFrom.remove(target);
        listTo.add(target);
        printLine("move");
        System.out.println(from + "=>" + to);
        pringMap();
    }

    private void pringMap() {
        List<Integer> listA = map.get(LIST_A);
        List<Integer> listB = map.get(LIST_B);
        List<Integer> listC = map.get(LIST_C);
        printLine("result");
        System.out.println("A=>" + listA);
        System.out.println("B=>" + listB);
        System.out.println("C=>" + listC);
    }

    private void printLine(String tag) {
        System.out.println("====" + tag + "====");
    }

结果:

====result====

A=>[4, 3, 2, 1]
B=>[]
C=>[]
====move====
A=>B
====result====
A=>[4, 3, 2]
B=>[1]
C=>[]
====move====
A=>C
====result====
A=>[4, 3]
B=>[1]
C=>[2]
====move====
B=>C
====result====
A=>[4, 3]
B=>[]
C=>[2, 1]
====move====
A=>B
====result====
A=>[4]
B=>[3]
C=>[2, 1]
====move====
C=>A
====result====
A=>[4, 1]
B=>[3]
C=>[2]
====move====
C=>B
====result====
A=>[4, 1]
B=>[3, 2]
C=>[]
====move====
A=>B
====result====
A=>[4]
B=>[3, 2, 1]
C=>[]
====move====
A=>C
====result====
A=>[]
B=>[3, 2, 1]
C=>[4]
====move====
B=>C
====result====
A=>[]
B=>[3, 2]
C=>[4, 1]
====move====
B=>A
====result====
A=>[2]
B=>[3]
C=>[4, 1]
====move====
C=>A
====result====
A=>[2, 1]
B=>[3]
C=>[4]
====move====
B=>C
====result====
A=>[2, 1]
B=>[]
C=>[4, 3]
====move====
A=>B
====result====
A=>[2]
B=>[1]
C=>[4, 3]
====move====
A=>C
====result====
A=>[]
B=>[1]
C=>[4, 3, 2]
====move====
B=>C
====result====
A=>[]
B=>[]

C=>[4, 3, 2, 1]


====result====
A=>[3, 2, 1]
B=>[]
C=>[]
====move====
A=>C
====result====
A=>[3, 2]
B=>[]
C=>[1]
====move====
A=>B
====result====
A=>[3]
B=>[2]
C=>[1]
====move====
C=>B
====result====
A=>[3]
B=>[2, 1]
C=>[]
====move====
A=>C
====result====
A=>[]
B=>[2, 1]
C=>[3]
====move====
B=>A
====result====
A=>[1]
B=>[2]
C=>[3]
====move====
B=>C
====result====
A=>[1]
B=>[]
C=>[3, 2]
====move====
A=>C
====result====
A=>[]
B=>[]

C=>[3, 2, 1]

二、汉诺塔非递归实现

一个美国学者总结得到:所有的汉诺塔移动可以总结为重复的两步,我们假设现在最小的圆盘在a柱子上,柱子为a,b,c

第一步:将最小圆盘移动到下一个柱子上,也就是b

第二步:对a柱子和c柱子进行顶上最小的元素进行判断,把小一点的那个圆盘移动到大一点的那个圆盘(有空则摞在空柱子上)。

重复上述两步就可以得到答案。


public class HanioStack2 {

    private static final String LIST_A = "A";
    private static final String LIST_B = "B";
    private static final String LIST_C = "C";


    public static void main(String[] args) {
        //36817
//        List<Integer> list = new ArrayList<>();
//        System.out.println(list.get(0));
        HanioStack2 hanio = new HanioStack2();
        long starTime = System.currentTimeMillis();
        hanio.init(20);
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - starTime);
        System.out.println(hanio.getMax());
    }

    private Map<String, List<Integer>> map = new HashMap<>();

    private int n;
    int max = 0;
    private String[] zhus;

    public int getMax() {
        return max;
    }

    public void init(int n) {
        this.n = n;
        if (n % 2 == 0) {
            zhus = new String[]{LIST_A, LIST_B, LIST_C};
        } else {
            zhus = new String[]{LIST_A, LIST_C, LIST_B};
        }
        List<Integer> listA = new ArrayList<>();
        map.put(LIST_A, listA);
        map.put(LIST_B, new ArrayList<>());
        map.put(LIST_C, new ArrayList<>());

        for (int i = n; i > 0; i--) {
            listA.add(i);
        }
        pringMap();
        startMove();
    }

    public void startMove() {
        int min = 0;
        int minNext = min + 1;
        int minNext2 = minNext + 1;
        int minNextValue;
        int minNext2Value;
        while (true) {
            action(zhus[min], zhus[minNext]);
            min = minNext;
            minNext = (min + 1) % 3;
            minNext2 = (minNext + 1) % 3;
            minNextValue = getListTop(minNext);
            minNext2Value = getListTop(minNext2);
            if (minNextValue == minNext2Value) {
                break;
            }
            if (minNextValue > minNext2Value) {
                action(zhus[minNext2], zhus[minNext]);
            } else if (minNextValue < minNext2Value) {
                action(zhus[minNext], zhus[minNext2]);
            }
        }
    }

    public int getListTop(int index) {
        List<Integer> list;
        switch (index) {
            case 0:
                list = map.get(zhus[0]);
                break;
            case 1:
                list = map.get(zhus[1]);
                break;
            case 2:
                list = map.get(zhus[2]);
                break;
            default:
                return Integer.MAX_VALUE;
        }
        if (list.isEmpty()) {
            return Integer.MAX_VALUE;
        }
        return list.get(list.size() - 1);
    }

    private void action(String from, String to) {
        List<Integer> listFrom = map.get(from);
        List<Integer> listTo = map.get(to);
        Integer target = listFrom.get(listFrom.size() - 1);
        listFrom.remove(target);
        listTo.add(target);
        printLine("action");
        System.out.println(from + "=>" + to);
        pringMap();
    }

    private void pringMap() {
        List<Integer> listA = map.get(LIST_A);
        List<Integer> listB = map.get(LIST_B);
        List<Integer> listC = map.get(LIST_C);
        printLine("result");
        System.out.println("A=>" + listA);
        System.out.println("B=>" + listB);
        System.out.println("C=>" + listC);
    }

    private void printLine(String tag) {
        System.out.println("====" + tag + "====");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值