分治算法_漢諾塔問題_Java實現

轉載請註明出處:http://blog.csdn.net/ljmingcom304/article/details/50296939
本文出自:【梁敬明的博客】

1.分治算法

  什麼是分治算法?就是將一個難以解決的大問題,分割成一些規模較小並且相對獨立的相同問題,以便各個擊破,分而治之。

2.漢諾塔問題  

  漢諾塔問題是一個十分經典的可以通過分治算法解決的問題,存在A、B、C大小形同的3根石柱,其中A石柱從下往上按照大小順序依次擺放着n個盤子,現在需要將A石柱的盤子全部移動到C石柱上,並且每次只能移動一個圓盤,小圓盤不能放在大圓盤上,請問該如何移動?

漢諾塔
  

3.算法分析  

  當n=1時,也就是剛開始A石柱上僅僅擺放一個圓盤,那麼直接將圓盤從A石柱上移動到B石柱上即可。
  當n=2時,從上往下按照大小順序將圓盤編爲1號和2號,那麼要將圓盤全部從石柱A移動到石柱C,首先需要將1號圓盤移動到石柱B,再將2號圓盤移動到石柱C,最後將1號圓盤移動到石柱C。
  當n=3時,仍然從上往下按照大小順序將圓盤編爲1號、2號和3號,此時由於問題相對複雜,所以1號和2號圓盤看做一個圓盤,即1+2號圓盤,此時需要解決的就是將1+2號圓盤和3號圓盤移動到石柱C的問題,即先將1+2號圓盤移動到石柱B,再將3號圓盤移動到石柱C,最後將1+2號圓盤移動到石柱C即可。
  由於每次只能移動一個圓盤,那麼如果要將1+2號圓盤移動到石柱B,需要將1+2號圓盤拆分爲兩個個體,看做將1號和2號圓盤移動到石柱B,同理將1+2號圓盤移動到石柱C。
  以此類推……
  當n=n時,將圓盤自上向下編爲1號、2號、3號……n號,同理將1號到n-1號圓盤看做一個圓盤,即 n1(n1) 號圓盤,此時解決的就是將 n1(n1) 號圓盤和n號圓盤移動到石柱C的問題,即先將n1(n1) 號圓盤移動到石柱B,再將n號圓盤移動到石柱C,最後將n1(n1) 號圓盤移動到石柱C。因爲將第n號圓盤移動到石柱C後,無論前n-1個圓盤怎麼移動,都不需要再次移動第n號圓盤,即父問題與子問題相對獨立且互不影響,因此可以將n1(n1) 號圓盤的問題同理向下拆分移動。
  示例代碼:

public class FZSFProblem {

    public static void main(String[] args) {
        solve(3);
    }

    public static void solve(int n) {
        // 已知條件n個圓盤和A、B、C三根石柱
        hanoi(n, "A", "B", "C");
    }

    /**
     * 若要讓第n個圓盤成功從A移動到C,需要讓前n-1個圓盤先從A移動到B,然後讓第n個圓盤從A移動到C,
     * 最後讓第n-1個圓盤從B移動到C,至於如何將前n-1個圓盤從A移動到B或者從A移動到C,僅僅是和父問
     * 題相同的子問題,採用父問題的解決方案即可。
     */
    private static void hanoi(int n, String a, String b, String c) {
        if (n == 1) {
            // 只有一個圓盤時直接從A石柱移動到C石柱
            move(n, a, c);
        } else {
            // 將前n-1個圓盤從石柱A移動到石柱B
            hanoi(n - 1, a, c, b);
            // 將第n號圓盤從石柱A移動到石柱C
            move(n, a, c);
            // 將前n-1個圓盤從石柱B移動到石柱C
            hanoi(n - 1, b, a, c);
        }
    }

    private static void move(int n, String i, String j) {
        System.out.println("第" + n + "個圓盤," + "從" + i + "移動到" + j);
    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章