汉诺塔


一、问题描述

在三根柱子之间一次只能移动一个圆盘,在小圆盘上不能放大圆盘。

二、算法分析

依据分治的策略,将问题化简为两个圆盘,三根柱子 A、B、C,首先解决倒数第二个圆盘的移动,将 n - 1(小盘) 从 A 移到 B,然后将 n(大盘) 从 A 移到 C,再将小盘从 B 移到 C。

子问题分别为:小盘和大盘的移动

三、代码实现

#include <stdio.h>
#include <stdlib.h>

#define num  5

static int a[num] = { 1, 2, 3, 4, 5 };  // 1 - 最小的物品    5 - 最大的物品
static int b[num] = { 0 };  // 0 - 为空
static int c[num] = { 0 };  // 0 - 为空
static int idxA = 0; // 当前有物品的下标
static int idxB = num;
static int idxC = num;

/// 定义 move 函数,移动物品
void move(char from, char to)
{
    int x = 0;
    
    printf("%c -> %c
", from, to);

    // 移出
    if (from == 'A' && idxA > -1 && idxA < num) {
        x = a[idxA];
        a[idxA] = 0;
        idxA++;
    }
    else if (from == 'B' && idxB > -1 && idxB < num) {
        x = b[idxB];
        b[idxB] = 0;
        idxB++;
    }
    else if (from == 'C' && idxC > -1 && idxC < num) {
        x = c[idxC];
        c[idxC] = 0;
        idxC++;
    }
    else {
        printf("%c from 数组越界!", from);
        return;
    }
    
    // 存入
    if (to == 'A' && --idxA > -1 && idxA < num) {
        a[idxA] = x;
    }
    else if (to == 'B' && --idxB > -1 && idxB < num) {
        b[idxB] = x;
    }
    else if (to == 'C' && --idxC > -1 && idxC < num){
        c[idxC] = x;
    }
    else {
        printf("%c to 数组越界!", to);
        return;
    }
    
    // 打印移动后结果
    for (int i = 0; i < num; i++) {
        printf("%d      %d      %d
", a[i], b[i], c[i]);
    }
    printf("
");
}

/// 将 n 个物品从 one 座借助 two 座,移到 three 座
void hanoi(int n, char one, char two, char three)
{
    if(n == 1) {
        move(one, three); // 只有一个物品,直接移动
    }
    else {
        hanoi(n-1, one, three, two); //首先把 n - 1 个从 one 移动到 two
        move(one, three); // 然后把最后一个 n 从 one 移动到 three
        hanoi(n-1, two, one, three); // 最后再把 n - 1 个从 two 移动到 three
    }
}

int main()
{
    hanoi(num, 'A', 'B', 'C');
    
    return 0;
}

A -> C
0      0      0
2      0      0
3      0      0
4      0      0
5      0      1

A -> B
0      0      0
0      0      0
3      0      0
4      0      0
5      2      1

C -> B
0      0      0
0      0      0
3      0      0
4      1      0
5      2      0

A -> C
0      0      0
0      0      0
0      0      0
4      1      0
5      2      3

B -> A
0      0      0
0      0      0
1      0      0
4      0      0
5      2      3

B -> C
0      0      0
0      0      0
1      0      0
4      0      2
5      0      3

A -> C
0      0      0
0      0      0
0      0      1
4      0      2
5      0      3

A -> B
0      0      0
0      0      0
0      0      1
0      0      2
5      4      3

C -> B
0      0      0
0      0      0
0      0      0
0      1      2
5      4      3

C -> A
0      0      0
0      0      0
0      0      0
2      1      0
5      4      3

B -> A
0      0      0
0      0      0
1      0      0
2      0      0
5      4      3

C -> B
0      0      0
0      0      0
1      0      0
2      3      0
5      4      0

A -> C
0      0      0
0      0      0
0      0      0
2      3      0
5      4      1

A -> B
0      0      0
0      0      0
0      2      0
0      3      0
5      4      1

C -> B
0      0      0
0      1      0
0      2      0
0      3      0
5      4      0

A -> C
0      0      0
0      1      0
0      2      0
0      3      0
0      4      5

B -> A
0      0      0
0      0      0
0      2      0
0      3      0
1      4      5

B -> C
0      0      0
0      0      0
0      0      0
0      3      2
1      4      5

A -> C
0      0      0
0      0      0
0      0      1
0      3      2
0      4      5

B -> A
0      0      0
0      0      0
0      0      1
0      0      2
3      4      5

C -> B
0      0      0
0      0      0
0      0      0
0      1      2
3      4      5

C -> A
0      0      0
0      0      0
0      0      0
2      1      0
3      4      5

B -> A
0      0      0
0      0      0
1      0      0
2      0      0
3      4      5

B -> C
0      0      0
0      0      0
1      0      0
2      0      4
3      0      5

A -> C
0      0      0
0      0      0
0      0      1
2      0      4
3      0      5

A -> B
0      0      0
0      0      0
0      0      1
0      0      4
3      2      5

C -> B
0      0      0
0      0      0
0      0      0
0      1      4
3      2      5

A -> C
0      0      0
0      0      0
0      0      3
0      1      4
0      2      5

B -> A
0      0      0
0      0      0
0      0      3
0      0      4
1      2      5

B -> C
0      0      0
0      0      2
0      0      3
0      0      4
1      0      5

A -> C
0      0      1
0      0      2
0      0      3
0      0      4
0      0      5

四、内容来源

汉诺塔

原文地址:https://www.cnblogs.com/dins/p/hanoi.html