C#中漢諾塔問題的遞歸解法


百度測試部2015年10月份的面試題之——漢諾塔。

漢諾塔就是將一摞盤子從一個塔轉移到另一個塔的游戲,中間有一個用來過度盤子的輔助塔。

百度百科在此

游戲試玩在此

用遞歸的思想解決漢諾塔問題就是分為兩種情況:

第一種情況是只有一個盤子的情況,也就是最基本的情況,這種情況下,直接將該盤子從原始塔轉移到目標塔即可勝利;

第二種情況是右n個盤子的情況,也就是普遍情況,這種情況下,要將除了最底下的那個盤子以外的(n-1)個盤子從原始塔轉移到輔助塔,再把最底下的那個盤子(第n個盤子)從原始塔轉移到目標塔,最后將輔助塔的(n-1)個盤子從輔助塔轉移到目標塔。

而第二種情況中(n-1)個盤子的問題又可以拆分成(n-2)個盤子和一個盤子的問題——

而(n-2)個盤子的問題又可以拆分成(n-3個情況)和一個盤子的問題——

……

最終可以拆分成(n-(n-1))個盤子的問題,也就是一個盤子的問題,這時候問題就變成了第一種情況——

將這個盤子從原始塔轉移到目標塔即可。

以上就是遞歸的思想在解漢諾塔游戲中的應用,我們可以理解這種遞歸法為類似數學歸納法的逆向思維法:

數學歸納法是一種從問題最基本情況的求解過程通過找規律從而得出該問題普遍情況的求解過程的方法;

遞歸法是將對問題普遍情況的求解過程進行拆分,最后分解為對一種最基本情況的求解過程的方法。

通過遞歸法解決漢諾塔的移動順序問題代碼如下:

using System;

namespace HanoiTower
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Int32.Parse(Console.ReadLine());
            Hanoi(n,"TowerA","TowerB","TowerC");
            Console.ReadLine();
        }

        private static void Hanoi(int n, string origin, string temp, string destination)
        {
            if (n == 1)
            {
                move(origin, destination);
            }
            else
            {
                Hanoi(n - 1, origin, destination, temp);
                move(origin, destination);
                Hanoi(n - 1, temp, origin, destination);
            }
        }

        private static void move(string origin, string destination)
        {
            Console.WriteLine("Move the plate from " + origin + " to " + destination);
        }
    }
}

運行結果如下(以三個盤子的情況為例,大家可以去游戲中操作來驗證解的正確性):


免責聲明!

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



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