漢諾塔算法
漢諾塔問題時一個典型的遞歸算法問題,可以先從簡單的3層漢諾塔入手。假設有ABC三根棒子,初始狀態時,A棒上放着3個圓盤,將其移動到C棒上,可以用B棒暫時放置圓盤。並且規定一次只能移動一個圓盤,且圓盤在放到棒上時,大的只能放在小的下面。
使用遞歸思想,可以採用以下步驟來完成圓盤的移動:
(1)將A棒上的兩個圓盤(圓盤1和圓盤2)移到B棒上;
(2)將A棒上剩下的一個圓盤移到C棒上;
(3)將B棒上的兩個圓盤(圓盤1和圓盤2)移到C棒上,即移動完成。
這裏第一步和第三步是移動多個圓盤的操作,可以採用遞歸的思想,仍然使用上述步驟來完成。
將上述解決問題的步驟加以推廣,便可得到如下遞歸求解漢諾塔算法:
如果只有一個圓盤,則把該圓盤從A棒移動到C棒,完成移動。如果圓盤數量 n>1,移動圓盤的過程可分爲三步:
(1)將A棒上的n-1個圓盤移到B棒上;
(2)將A棒上的1個圓盤移到C棒上;
(3)將B棒上的n-1個圓盤移到C棒上。
其中,移動n-1個圓盤的工作可以歸結爲遞歸運算。
void hanoi(int n,char a,char b,char c){
// 只有一個盤子的時候,從A棒移動到C棒即可
if(n == 1){
System.out.printf("第%d次移動:圓盤從%c棒移動到%c棒%n",++count,a,c);
}else{
// 當有n個盤子時,將n-1個盤子先從A棒上移到緩衝B棒上
// 把A棒上剩下的1個圓盤移到終點C棒上
// 然後再將這n-1個盤子從緩衝b棒上移到終點C棒上
hanoi(n-1,a,c,b);
hanoi(1,a,b,c);
hanoi(n-1,b,a,c);
}
}
漢諾塔求解
public class HanoiTower {
// 漢諾塔——典型的遞歸算法問題
private static int count = 0;
// n爲盤子數量,a爲起點,b爲緩衝,c爲終點
public static void hanoi(int n,char a,char b,char c){
// 只有一個盤子的時候,從A棒移動到C棒即可
if(n == 1){
System.out.printf("第%d次移動:圓盤從%c棒移動到%c棒%n",++count,a,c);
}else{
// 當有n個盤子時,將n-1個盤子先從A棒上移到緩衝B棒上
// 把A棒上剩下的1個圓盤移到終點C棒上
// 然後再將這n-1個盤子從緩衝b棒上移到終點C棒上
hanoi(n-1,a,c,b);
hanoi(1,a,b,c);
hanoi(n-1,b,a,c);
}
}
public static void main(String[] args) {
System.out.println("***漢諾塔問題求解***");
System.out.println("請輸入漢諾塔圓盤的數量:");
Scanner input = new Scanner(System.in);
int n = input.nextInt();
hanoi(n,'A','B','C');
System.out.printf("求解完畢,總共需要%d步移動!",count);
}
}
運行代碼結果如下:
***漢諾塔問題求解***
請輸入漢諾塔圓盤的數量:
3
第1次移動:圓盤從A棒移動到C棒
第2次移動:圓盤從A棒移動到B棒
第3次移動:圓盤從C棒移動到B棒
第4次移動:圓盤從A棒移動到C棒
第5次移動:圓盤從B棒移動到A棒
第6次移動:圓盤從B棒移動到C棒
第7次移動:圓盤從A棒移動到C棒
求解完畢,總共需要7步移動!