漢諾塔實現方法
阿新 • • 發佈:2020-10-14
首選,規定一個包含有棧的類,對應抽象漢諾塔
class HanoiStack { public string TowerName { get; set; } //對應漢諾塔的塔名稱,如:A,B,C public Stack<int> TowerStack { get;set; } //棧,先進後出,跟漢諾塔的玩法很相符 }
然後,漢諾塔的搬運規則,其核心就是:當若只有一個盤時,直接將盤從源塔柱搬移到目標塔柱,否則,遞迴上一步搬移,直至僅有一個盤
即,n=1,源塔柱 --> 目標塔柱;n>1,遞迴直至僅有一個盤
/// <summary> /// 漢諾塔搬運規律 /// </summary> /// <param name="n">總的盤數</param> /// <param name="from">源塔柱</param> /// <param name="to">目標塔柱</param> /// <param name="transfer">中轉塔柱</param> private void Hanoi(int n, HanoiStack from, HanoiStack to, HanoiStack transfer) { if (n <= 1) HanoiMove(from, to, transfer); //只有一個盤,則直接從源塔柱搬移到目標塔柱,否則遞迴直至僅有一個盤 else { Hanoi(n - 1, from, transfer, to); Hanoi(1, from, to, transfer); Hanoi(n - 1, transfer, to, from); } }
再就是,搬運以及列印顯示,列印顯示的方式個人開心就好
private void HanoiMove(HanoiStack from, HanoiStack to, HanoiStack transfer) { to.TowerStack.Push(from.TowerStack.Pop()); //搬運,從 源塔柱 中取出最頂端的一個“盤”,放入 目標塔柱 的頂端 RichTextBoxAppendLine(richTextBox_Hanoi, $" Move No.{to.TowerStack.Peek()}:{from.TowerName} -> {to.TowerName} via {transfer.TowerName}", Color.DarkSeaGreen, true); //列印顯示 }
最後,函式呼叫
private void Hanoi_Start(int total) { int n = total; HanoiStack a = new HanoiStack() { TowerName = "A", TowerStack = new Stack<int>() }; HanoiStack b = new HanoiStack() { TowerName = "B", TowerStack = new Stack<int>() }; HanoiStack c = new HanoiStack() { TowerName = "C", TowerStack = new Stack<int>() }; while (total-- > 0) a.TowerStack.Push(total + 1); //初始化棧 Hanoi(n, a, c, b); }
執行效果,測試用例是:15,漢諾塔的搬移步驟總數為,2 的 n 次方減 1,即:2^n-1,
當 n=15,搬移的步驟總數為:2^15-1 = 32767,
執行結果,搬移步驟總數為 32767,耗時 03分03秒 50毫秒
搬移過程,下圖所示,如:Move No.1:A -> C via B ,
表示:將1號盤(No.1)從 A 塔柱通過 B 塔柱搬移到 C 塔柱
實際操作為:直接將1號盤(No.1)從 A 塔柱搬移到 C 塔柱
author:韋小明
本文即原文:漢諾塔實現方法