1. 程式人生 > >分治演算法_漢諾塔問題_Java實現

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

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);
    }

}

相關推薦

分治演算法_問題_Java實現

1.分治演算法   什麼是分治演算法?就是將一個難以解決的大問題,分割成一些規模較小並且相對獨立的相同問題,以便各個擊破,分而治之。 2.漢諾塔問題     漢諾塔問題是一個十分經典的可以通過分治演算法解決的問題,存在A、B、C大小形同的3根石

演算法--python3實現

0.摘要 本文使用python3實現漢諾塔問題。  1.問題闡述與分析 有三個柱子A,B,C,每個柱子上都可以放置圓盤。最初,所有圓盤都在A柱子上,需要把所有圓盤都移動到C柱子上。 要求: 1.每次只移動一個圓盤 2.只能移動柱子最上面的圓盤 3.保證每根柱

遞歸_問題

遞歸 [] post pre span pub static oid for public class Tower { static int nDisks=3;//盤子的個數 public static void main(String[] agrs) {

python數據結構_遞歸_問題

代碼 nbsp 需要 數學歸納法 else 過去 所有 我們 但是 已經不是第一次寫這個漢諾塔問題, 其實遞歸還真是不太好理解, 因為遞歸這種是想其實有點反人類, 為什麽? 因為不太清楚, 寫個循環一目了然, 用遞歸其實要把核心邏輯理清楚, 要不根本沒法進行下去 所有才有了

演算法

演算法的概念 計算過程,解決問題的方法 Niklaus Wirth: '程式=資料結構+演算法' 時間複雜度 看下面四組程式碼時間執行最短的是哪個? print('hello world') O(1) for i in range(n): O(n) print('hello

Python遞迴呼叫_問題

遞迴函式的優點是定義簡單,邏輯清晰。理論上,所有的遞迴函式都可以寫成迴圈的方式,但迴圈的邏輯不如遞迴清晰。 使用遞迴函式需要注意防止棧溢位。在計算機中,函式呼叫是通過棧(stack)這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧幀。由於棧的大

遞迴經典案例 python實現

背景資料:  漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間

遞迴演算法處理

package com.cn.ygm.hanoiTower; public class HanoiTower { /** * 移動盤子 * topN:移動的盤子數 * from:起始塔座 * inter:中間塔座 * to:目標塔座

演算法問題 Hanoi Tower

題目內容    漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大

三柱c++實現

小的盤子必須在大的盤子的上面 void hannoi(int n, char a, char b, char c ) {     if (n == 1)     {         res.push_back(to_string(n)+" from " +a+" to "+

Problem A: 深入淺出學演算法022-問題II

#include<stdio.h> void hanio(int n,char a,char b,char c) { if(n==1) printf("%c->%c\n",a,c); else{ hanio(n-1,a,c,b);

遞迴演算法問題

一、遞迴演算法   遞迴是一種常見的解決問題的演算法,即把問題逐漸簡單化。遞迴的基本思想就是“自己呼叫自己”,一個使用遞迴技術的方法將會直接或者間接的呼叫自己。   遞迴結構包括兩個部分: 定義遞迴頭:說明什麼時候不呼叫自身方法,因為如果沒有定義遞迴頭,將陷入

演算法 Python 版

題目: 漢諾塔給出最優解,如果對漢諾塔的定義有不瞭解,請翻看資料結構教材。 除了最基本的之外,還有一題,給定一個數組,arr=[2,3,1,2,3],其含義是這是一個有5個圓盤的漢諾塔,每一個數字代表這個圓盤所在的位置,1代表左邊的柱子,2代表中間,3代表

C語言習題5.20--演算法

漢諾塔(又稱河內塔)問題是印度的一個古老的傳說。開天闢地的神勃拉瑪在一個廟裡留下了三根金剛石的棒A、B和C,A上面套著n個圓的金片,最大的一個在底下,其餘一個比一個小,依次疊上去,廟裡的眾僧不倦地把它們一個個地從A棒搬到C棒上,規定可利用中間的一根B棒作為幫助,但每次只能搬一個,而且大的不能放在小的上面。

簡單演算法解決問題

漢諾塔:漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三

演算法時間複雜度計算

 設a, b, c是3個塔座:開始時,塔座a上有n個自上而下、由小到大地疊在一起圓盤,各圓盤從小到大編號為1, 2, …, n,現要求將塔座a上的這一疊圓盤移到塔座b上,並仍按同樣順序疊置,移動圓盤時遵守以下移動規則: 規則1:每次只能移動1個圓盤; 規則2:不允許將較大的圓

(優秀演算法)對經典遞迴問題的理解與講解(部分引用大神程式碼,附連結。)

部落格大神的優秀漢諾塔程式碼:喜歡特別冷的冬天下著雪   (侵權聯絡) 本文只是在大神思路的基礎上加以理解。 [cpp] view plain copy  print? #include <stdio.h> //第一個塔為初始塔,中間的塔為借用塔,

shell實現

#!/bin/bash #利用函式實現漢洛塔問題(需要使用者輸入盤子數,輸出每個盤子的移動步驟,盤子從上到下為編號為n-1) #輸入提示 a=a b=b c=c function mv() { if [ $1 -eq "1" ];then echo  "$2 -> $

每天一道演算法題——

漢諾塔如圖所示,把圓盤從下面開始按大小順序重新擺放在另一根柱子上,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。 它的解法可以採用分解法,把一個大的問題,逐步分解成一個個小問題。比如我們想把A中的盤子挪到B上,可以把問題分解成,將A的前n-1個盤子先挪到C,然

【SHELL】 3個實現

3個漢諾塔的實現。漢諾塔的問題的具體描述就不再重複了。直接上程式碼。 1 #!/bin/bash 2 Time_Initial=`date "+s:%s"|awk -F":" '{printf($2)}'` 3 a=a #A柱,也可以理解為源