# 汉诺塔问题的思考

### 2、抽象为数学的问题

(1)以C盘为中介，从A杆将1至n-1号盘移至B杆；
(2)将A杆中剩下的第n号盘移至C杆；
(3)以A杆为中介；从B杆将1至n-1号盘移至C杆。

H(1)=1;
H(n)=2*H(n-1)+1;（n>1）

H(n) = 2*(2*H(n-2)+1)+1
H(n) = 2²*H(n-2) + 2 + 1
...
H(n) = 2^(n-1)*H(n-(n-1)) + 2^(n-2) + ... + 2^1 + 1
H(n) = 2^(n-1)*H(1) + 2^(n-2) + ... + 2^1 + 1
H(n) = 2^(n-1) + 2^(n-2) + ... + 2^1 + 1

2*H(n) = 2^(n) +2^(n-1) + 2^(n-2) + ... + 2^2 + 2^1

2*H(n) - H(n) = 2^(n) - 1

H(n) = 2^(n) - 1 ;(n>0)

### 3、编码模拟移动过程

num，表示需要移动的盘子个数；使用递归调用来模拟移动；递归到 n = 1 时停止

``````    private List<String> arrayⅠ;
private List<String> arrayⅡ;
private List<String> arrayⅢ;
//移动的步数
private double moveAmount = 0;

private void startHanoi(int num) {
moveAmount = 0;
arrayⅠ = new ArrayList<>();
arrayⅡ = new ArrayList<>();
arrayⅢ = new ArrayList<>();
for (int i = 1; i <= num; i++) {
}
Log.i("move", "arrayⅠ-" + toStringByArray(arrayⅠ));
hanoi(num, 'Ⅰ', 'Ⅱ', 'Ⅲ');
}

/**
* @param n           盘子的数目
* @param origin      源座
* @param assist      辅助座
* @param destination 目的座
*/
private void hanoi(int n, char origin, char assist, char destination) {
if (n == 1) {
move(origin, destination);
} else {
hanoi(n - 1, origin, destination, assist);
move(origin, destination);
hanoi(n - 1, assist, origin, destination);
}
}

private void move(char origin, char destination) {
moveAmount++;
Log.i("move", origin + "--->" + destination);
//移动的盘子编号
String moveNum = null;
switch (origin) {
case 'Ⅰ':
moveNum = arrayⅠ.get(0);
arrayⅠ.remove(0);
break;
case 'Ⅱ':
moveNum = arrayⅡ.get(0);
arrayⅡ.remove(0);
break;
case 'Ⅲ':
moveNum = arrayⅢ.get(0);
arrayⅢ.remove(0);
break;
default:
break;
}
switch (destination) {
case 'Ⅰ':
break;
case 'Ⅱ':
break;
case 'Ⅲ':
break;
default:
break;
}
Log.i("move", "arrayⅠ-" + toStringByArray(arrayⅠ));
Log.i("move", "arrayⅡ-" + toStringByArray(arrayⅡ));
Log.i("move", "arrayⅢ-" + toStringByArray(arrayⅢ));
Log.i("move", "移动" + moveAmount + "步");
Log.i("move", "---------------------");
}

private String toStringByArray(@NonNull List<String> array) {
StringBuilder sb = new StringBuilder();
for (String s : array) {
sb.append(s);
}
return sb.toString();
}
``````
• 盘数为3时的移动过程