漢諾塔問題中的遞歸思想

漢諾塔問題

如下圖所示,從左到右有A、B、C三根柱子,其中A柱子上面有從小疊到大的n個圓盤,現要求將A柱子上的圓盤移到C柱子上去,期間只有一個原則:一次只能移到一個盤子且大盤子不能在小盤子上面,求移動的步驟和移動的次數?

 這是一個經典的體現遞歸思想的案例。

假設將n個盤子由A挪至C需要的操作次數爲f(n),可以按以下步驟求解:

  • 將n個碟子從A挪到C,等於先將最上面n-1個碟子經由C從A挪到B (操作次數即f(n-1)),
  • 然後將A上剩餘的1個碟子放到C (操作次數1次)
  • 最後再將B上的n-1個碟子經由A挪到C上 (操作次數f(n-1))
  • 所以f(n) = 2f(n-1)+1,得出f(n)=2^n-1

Java代碼如下 


public class Hanoi {
    
    //操作步驟數
    private static int steps = 1;

    public static void main(String[] args) {
        //盤子數目
        int diskNumber = 4;
        doTowers(diskNumber, 'A', 'B', 'C');
    }

    private static void doTowers(int diskNum, char from , char via, char to){
        if (diskNum>1){
            //針對盤子數目爲diskNum的盤子堆,先將最上面的diskNum-1個盤子(即Disk 1~Disk diskNum-1)挪至中轉位置
            doTowers(diskNum-1, from, to, via);
            //將剩餘的最下面的一個盤子(即Disk diskNum)直接一步挪到位
            System.out.println("Step " + steps + ": " + "Disc" + diskNum + " " + from + "-->" + to);
            steps++;
            //將中轉位置的diskNum-1個盤子(即Disk 1~Disk diskNum-1)挪至終點位置
            doTowers(diskNum-1, via, from, to);
        }
        //最上面那個碟子,即Disk1,從A挪到C
        else {
            System.out.println("Step " + steps + ": "+ "Disk1 " + from + "-->" + to);
            steps++;
        }
    }

}

測試:以4個盤子爲例,運行結果如下。

Step 1: Disk1 A-->B
Step 2: Disc2 A-->C
Step 3: Disk1 B-->C
Step 4: Disc3 A-->B
Step 5: Disk1 C-->A
Step 6: Disc2 C-->B
Step 7: Disk1 A-->B
Step 8: Disc4 A-->C
Step 9: Disk1 B-->C
Step 10: Disc2 B-->A
Step 11: Disk1 C-->A
Step 12: Disc3 B-->C
Step 13: Disk1 A-->B
Step 14: Disc2 A-->C
Step 15: Disk1 B-->C

發佈了15 篇原創文章 · 獲贊 159 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章