算法基礎三:分治算法---漢諾塔問題


算法基礎三:分治算法---漢諾塔問題

一、遞歸與分治

​ 很多有用的算法是遞歸(recursive)結構的:為了解決一個給定的問題,遞歸地調用自身一次或者多次來解決關系密切的若干個子問題。這樣的算法通常遵循分治(divide and conque)方法:它們將問題分解成若干個與原問題相似而規模較小的子問題,遞歸地解決這些子問題,然后把子問題的解合並成原問題的一個解。

分治范式在每一層遞歸包括三個步驟:

  • 分解:將問題分解成若干個子問題
  • 治理:遞歸地解決各子問題。不過若子問題的規模足夠小,就直接解決。
  • 合並:將子問題的解合並成原問題的一個解

二、漢諾塔問題與遞歸

1、算法的描述與分析

​ n個大小不同的圓盤(中心有孔,按照尺寸從小到大一次編號為1,2,3,...,n)按尺寸大小(大在下,小在上)疊放在3根桿(編號為A、B和C)的A號桿上,每次移動一個盤,將這n個盤從A號桿移動到C號桿上。移動的過程中不允許大盤疊放在小盤上。要求以最少的移動步驟達到移動目標。

image-20210919203225404

2、偽代碼描述

image-20210919203247570

3、解題步驟分析:

第一步:
	把n-1個模塊	從塔1移動到塔2
	把第n個模塊  從塔1移動到塔3
第二部:
	把n-1個模塊  從塔2移動到塔3

三、代碼實現

1、Java語言實現

public class Hanoi {

    static int m =0;//標記移動次數
    //實現移動的函數
    public static void move(int disks,char N,char M)
    {
        System.out.println("第" + (++m) +" 次移動 : " +" 把 "+ disks+" 號圓盤從 " + N +" ->移到->  " + M);
    }
    //遞歸實現漢諾塔的函數
    public static int hanoi(int n,char A,char B,char C)
    {
        if(n == 1)//圓盤只有一個時,只需將其從A塔移到C塔
            Hanoi.move(1, A, C);//將編b號為1的圓盤從A移到C
        else
        {//否則
            hanoi(n - 1, A, C, B);//遞歸,把A塔上編號1~n-1的圓盤移到B上,以C為輔助塔
            Hanoi.move(n, A, C);//把A塔上編號為n的圓盤移到C上
            hanoi(n - 1, B, A, C);//第二步:遞歸,把B塔上編號1~n-1的圓盤移到C上,以A為輔助塔
        }
        return m;
    }

}

2、測試

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner imput = new Scanner(System.in);
        char A = 'A';
        char B = 'B';
        char C = 'C';
        System.out.println("******************************************************************************************");
        System.out.println("這是漢諾塔問題(把A塔上編號從小號到大號的圓盤從A塔通過B輔助塔移動到C塔上去");
        System.out.println("******************************************************************************************");
        System.out.print("請輸入圓盤的個數:");
        int disks = imput.nextInt();
        int m = Hanoi.hanoi(disks, A, B, C);
        System.out.println(">>移動了" + m + "次,把A上的圓盤都移動到了C上");
        imput.close();
    }
}

四、遞歸與分治感悟

​ 通過漢諾塔問題,學習到了把一個大問題分解成若干個小問題,最終分解成最簡單的一個問題,也就是遞歸地結束點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM