漢諾塔是展示遞歸分治思想的教科書級範例。本文詳細解析 C 語言遞歸實作漢諾塔移動邏輯,包含演算法證明、步數計算、以及非遞歸改寫思路。
遞歸分解邏輯:
#include <stdio.h>
void hanoi(int n, char from, char aux, char to);
int main() {
int n;
printf("請輸入圓盤數量: ");
scanf("%d", &n);
printf("移動步驟 (共 %d 步):\n", (1 << n) - 1);
hanoi(n, 'A', 'B', 'C');
return 0;
}
void hanoi(int n, char from, char aux, char to) {
if (n == 1) {
printf("移動圓盤 %d: %c → %c\n", n, from, to);
return;
}
hanoi(n-1, from, to, aux); // 步驟 1
printf("移動圓盤 %d: %c → %c\n", n, from, to); // 步驟 2
hanoi(n-1, aux, from, to); // 步驟 3
}
n=3 時遞歸呼叫樹:
hanoi(3, A, B, C)
├── hanoi(2, A, C, B)
│ ├── hanoi(1, A, B, C) → A→C
│ ├── 移動圓盤 2: A→B
│ └── hanoi(1, C, A, B) → C→B
├── 移動圓盤 3: A→C
└── hanoi(2, B, A, C)
├── hanoi(1, B, C, A) → B→A
├── 移動圓盤 2: B→C
└── hanoi(1, A, B, C) → A→C
設 T(n) 為 n 圓盤最少移動步數:
n=64 時需 2⁶⁴-1 ≈ 1.84×10¹⁹ 步,若每秒一步需 5840 億年,印證傳說中世界末日時程。
利用圓盤移動規律:
void hanoi_iterative(int n) {
char pegs[3] = {'A', 'B', 'C'};
int total = (1 << n) - 1;
int dir = (n % 2 == 1) ? 1 : -1; // 奇數順時針,偶數逆時針
int pos[64] = {0}; // 記錄各圓盤位置索引 0,1,2
for (int step = 1; step <= total; step++) {
if (step % 2 == 1) { // 移動最小圓盤
int p = 0;
pos[p] = (pos[p] + dir + 3) % 3;
printf("移動圓盤 1: %c → %c\n", pegs[(pos[p]-dir+3)%3], pegs[pos[p]]);
} else { // 移動其他圓盤
// 找出唯一合法移動...
}
}
}
| 變體 | 特點 | 應用場景 |
|---|---|---|
| 四柱漢諾塔 | 最優解未知,Frame-Stewart 演算法 | 演算法研究 |
| 雙色漢諾塔 | 圓盤有顏色限制 | 約束優化問題 |
| 並行漢諾塔 | 多執行緒同時移動 | 分散式系統排程 |
漢諾塔雖屬玩具問題,但其蘊含的遞歸分治、指數複雜度、數學歸納證明等核心概念,是電腦科學基礎教育中不可或缺的基石。掌握其遞歸與迭代雙重實作,能顯著提升演算法設計與分析能力。