有A、B和C 3跟柱子,在A上從下往上按照從小到大的順序放着64個圓盤,以B爲中介,把盤子所有移動到C上。移動過程當中,要求任意盤子的下面要麼沒有盤子,要麼只能有比它大的盤子。java
* 思想:採用遞歸的方法來接
app
* 1. 先將A上面的n-1個盤子,移到B柱上
ui
* 2. 而後把A上最大的一個盤子放到C上去
this
* 3. 而後把B上面的n-1個盤子移到A上去
編碼
*
.net
* 步驟:
code
* 漢若塔用遞歸思考首先考慮一種臨界狀態,把n-1個上面的盤從A—B, 就是把n從A移動到C,最後把n-1個盤從B---C,
orm
* (注意在考慮把n-1個盤從B---C的時候就出現遞歸調用,若是把A,B盤交換就又重複上面的流程了,最後到n = 1的時候就返回)
遞歸
*
ci
* 僞代碼:
* public void run(int n, char a, char b, char c)
{
if(n==1)
{
move(n,a,c) //等於1的時候把盤從A移動到C
}else
{
run(n-1,a,b,c);//遞歸調用把a上面的n-1個盤移動到B上,怎麼表示移動?把柱子交換不就是移動了。
move(n,a,c);
run(n-1,b,a,c);//意圖是把n-1個盤從B移動到A上。
}
}
*
package cglib;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
public class StringNumber {
public static void main(String args[]) throws Exception {
int n;
BufferedReader buf =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("請輸入盤數:");
n = Integer.parseInt(buf.readLine());
StringNumber hanoi = new StringNumber();
hanoi.move(n, 'A', 'B', 'C');
}
public void move(int n, char a, char b, char c) {
if (n == 1)
System.out.println("盤 " + n + " 由 " + a + " 移至 " + c);
else {
move(n - 1, a, c, b);
System.out.println("盤 " + n + " 由 " + a + " 移至 " + c);
move(n - 1, b, a, c);
}
}
}
輸出:
請輸入盤數:5
盤 1 由 A 移至 C
盤 2 由 A 移至 B
盤 1 由 C 移至 B
盤 3 由 A 移至 C
盤 1 由 B 移至 A
盤 2 由 B 移至 C
盤 1 由 A 移至 C
盤 4 由 A 移至 B
盤 1 由 C 移至 B
盤 2 由 C 移至 A
盤 1 由 B 移至 A
盤 3 由 C 移至 B
盤 1 由 A 移至 C
盤 2 由 A 移至 B
盤 1 由 C 移至 B
盤 5 由 A 移至 C
盤 1 由 B 移至 A
盤 2 由 B 移至 C
盤 1 由 A 移至 C
盤 3 由 B 移至 A
盤 1 由 C 移至 B
盤 2 由 C 移至 A
盤 1 由 B 移至 A
盤 4 由 B 移至 C
盤 1 由 A 移至 C
盤 2 由 A 移至 B
盤 1 由 C 移至 B
盤 3 由 A 移至 C
盤 1 由 B 移至 A
盤 2 由 B 移至 C
盤 1 由 A 移至 C
①若是隻能移動到相鄰的 那麼n個圓盤須要
f(n)=(3^n)-1 次
②若是不加上只能移動到相鄰的限制的話 那麼n個圓盤須要f(n)=(2^n)-1次
- public class Hanoi {
- /**
- * @count記錄是第幾回移動
- */
- private static int count = 0;
- /**
- * @Describe_將塔座x上按直徑大小自上而下編碼爲123...n個圓盤按規則一到塔座Z上_y作輔助塔座
- * @param n圓盤的格式
- * @param x起始圓盤的位置
- * @param y輔助塔座
- * @param z目標塔座
- */
- public static void hanoi(int n, char x, char y, char z) {
- if (n == 1) {
- move(x, 1, z);//
- } else {
- hanoi(n - 1, x, z, y);// 將前n-1個從x移動到y,z當輔助
- move(x, n, z);// 將變化爲n的圓盤從x移動到z
- hanoi(n - 1, y, x, z);// 再將前n-1個圓盤從y移動到z,x當輔助
- }
- }
- /**
- * @Describe_移動操做_將編號爲n的圓盤從x移動到z
- * @param x
- * @param n
- * @param z
- */
- public static void move(char x, int n, char z) {
- System.out.println("第 " + (++count) + "次移動 :" + n + "號圓盤," + x + "-->"
- + z);
- }
- /**
- * @Describe_規則再次變化_再加上一個只能移動到相鄰的限制條件
- * @param n
- * @param x
- * @param y
- * @param z
- */
- public static void hanoi2(int n, char x, char y, char z) {
- if (n == 1) {
- move(x, 1, y);//
- move(y, 1, z);//
- } else {
- hanoi2(n - 1, x, y, z);// 將前n-1個從x移動到z,y當輔助
- move(x, n, y);// 將變化爲n的圓盤從x移動到y
- hanoi2(n - 1, z, y, x);// 再將前n-1個圓盤從z移動到x,y當輔助
- move(y, n, z);// 將變化爲n的圓盤從y移動到z
- hanoi2(n - 1, x, y, z);// 將前n-1個從x移動到z,y當輔助
- }
- }
- public static void main(String[] args) {
- // Hanoi.hanoi(4, 'x', 'y', 'z');//------能夠移動到相鄰的或者不相鄰的
- // Hanoi.hanoi2(4, 'x', 'y', 'z');//-----只能移動到相鄰的
- }
- }
用棧實現:
package cglib;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Stack;
public class StringNumber {
//塔
class Tower<E> {
//塔編號
private int number;
//塔名稱
private String name;
//存放盤子的棧
private Stack<E> stack = new Stack<E>();
public Tower(int number,String name) {
this.number = number;
this.name = name;
}
public int getNumber() {
return number;
}
public String getName() {
return name;
}
public Stack<E> getStack() {
return stack;
}
}
//盤子
class Tray {
//盤子編號
private int number;
//盤子名稱
private String name;
public Tray(int number,String name) {
this.number = number;
this.name = name;
}
public int getNumber() {
return number;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}
public <T> void hanoi(int num,Tower<T> from,Tower<T> middle,
Tower<T> to) {
if(num == 1) {
move(from,middle,to);
} else {
//將num-1個盤子從from塔上移到middle塔上
hanoi(num-1,from,to,middle);
//將第num個盤子移到to塔上
move(from,middle,to);
//將num-1個盤子從middle塔上移到to塔上
hanoi(num-1,middle,from,to);
}
}
private <E> void move(Tower<E> from,Tower<E> middle ,Tower<E> to) {
E tray = from.getStack().pop();
to.getStack().push(tray);
StringBuilder sb = new StringBuilder();
sb.append("=====================Hanoi.move()======================\n")
.append(" Move tray : ").append(((Tray)tray).getName())
.append(" from ").append(from.getName()).append(" to ")
.append(to.getName()).append("\n ")
.append(from.getName()).append(":").append(format(from)).append(",")
.append(middle.getName()).append(":").append(format(middle)).append(",")
.append(to.getName()).append(":").append(format(to));
System.out.println(sb.toString());
}
private <E> String format(Tower<E> tower) {
Iterator<E> i = tower.getStack().iterator();
if (! i.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
while(i.hasNext()) {
sb.append(i.next().toString()).append(",");
}
sb.replace(sb.length()-1, sb.length(), "]");
return sb.toString();
}
public static void main(String[] args) {
StringNumber hanoi = new StringNumber();
Tower<Tray> from = hanoi.new Tower<Tray>(1, "1號塔");
Tower<Tray> middle = hanoi.new Tower<Tray>(2, "2號塔");
Tower<Tray> to = hanoi.new Tower<Tray>(3, "3號塔");
int num = 4;
for (int i = num; i >0; i--) {
Tray tray = hanoi.new Tray(i,i+"號盤子");
from.getStack().push(tray);
}
hanoi.hanoi(num, from, middle, to);
}
}
輸出:=====================Hanoi.move()======================
Move tray : 1號盤子 from 1號塔 to 2號塔
1號塔:[4號盤子,3號盤子,2號盤子],3號塔:[],2號塔:[1號盤子]
=====================Hanoi.move()======================
Move tray : 2號盤子 from 1號塔 to 3號塔
1號塔:[4號盤子,3號盤子],2號塔:[1號盤子],3號塔:[2號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 2號塔 to 3號塔
2號塔:[],1號塔:[4號盤子,3號盤子],3號塔:[2號盤子,1號盤子]
=====================Hanoi.move()======================
Move tray : 3號盤子 from 1號塔 to 2號塔
1號塔:[4號盤子],3號塔:[2號盤子,1號盤子],2號塔:[3號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 3號塔 to 1號塔
3號塔:[2號盤子],2號塔:[3號盤子],1號塔:[4號盤子,1號盤子]
=====================Hanoi.move()======================
Move tray : 2號盤子 from 3號塔 to 2號塔
3號塔:[],1號塔:[4號盤子,1號盤子],2號塔:[3號盤子,2號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 1號塔 to 2號塔
1號塔:[4號盤子],3號塔:[],2號塔:[3號盤子,2號盤子,1號盤子]
=====================Hanoi.move()======================
Move tray : 4號盤子 from 1號塔 to 3號塔
1號塔:[],2號塔:[3號盤子,2號盤子,1號盤子],3號塔:[4號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 2號塔 to 3號塔
2號塔:[3號盤子,2號盤子],1號塔:[],3號塔:[4號盤子,1號盤子]
=====================Hanoi.move()======================
Move tray : 2號盤子 from 2號塔 to 1號塔
2號塔:[3號盤子],3號塔:[4號盤子,1號盤子],1號塔:[2號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 3號塔 to 1號塔
3號塔:[4號盤子],2號塔:[3號盤子],1號塔:[2號盤子,1號盤子]
=====================Hanoi.move()======================
Move tray : 3號盤子 from 2號塔 to 3號塔
2號塔:[],1號塔:[2號盤子,1號盤子],3號塔:[4號盤子,3號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 1號塔 to 2號塔
1號塔:[2號盤子],3號塔:[4號盤子,3號盤子],2號塔:[1號盤子]
=====================Hanoi.move()======================
Move tray : 2號盤子 from 1號塔 to 3號塔
1號塔:[],2號塔:[1號盤子],3號塔:[4號盤子,3號盤子,2號盤子]
=====================Hanoi.move()======================
Move tray : 1號盤子 from 2號塔 to 3號塔
2號塔:[],1號塔:[],3號塔:[4號盤子,3號盤子,2號盤子,1號盤子]
或者: