• 汉诺塔



    一、问题描述

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

    二、算法分析

    依据分治的策略,将问题化简为两个圆盘,三根柱子 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
    

    四、内容来源

    汉诺塔

  • 相关阅读:
    落花美眷,终究抵不过逝水流年,回忆我的2016,展望2017。
    如何对于几百行SQL语句进行优化?
    基于.NET Socket API 通信的综合应用
    数据库备份定期删除程序的开发。
    如何开发应用程序将客户服务器数据库的备份,下载到本地的云服务上?
    从大公司做.NET 开发跳槽后来到小公司的做.NET移动端微信开发的个人感慨
    asp.net mvc entity framework 数据库 练习(一)
    ASP.NET CORE小试牛刀:干货(完整源码)
    [开源].NET数据库访问框架Chloe.ORM
    SqlBulkCopy简单封装,让批量插入更方便
  • 原文地址:https://www.cnblogs.com/dins/p/hanoi.html
Copyright © 2020-2023  润新知