一、汉诺塔递归实现
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 + "===="); } }