汉诺塔问题的C 语言求解分析

最近看了一道求解递归的 汉诺塔问题 ,觉得很难理解 ,在网上找了很长时间 也没找到有说的 详细的, 然后自己又看了看, 把自己理解的写出来供大家参考下。


首先我们假设三根柱子分别是 A,B,C   由上到下 的 盘子依次是 1,2,3,。。N.

先假设只有两个盘子时的情况 其中A是 原点 B 是中间点 C 是目标点

当只有两个盘子时 很简单
1 将 1   从 A->B
2 将 2   从 A->C
3 将 1 从 B->C


再假设只有三个盘子时的情况

1 将 1 从 A->C
2 将 2 从 A->B
3 将 1 从 C->B
4 将 3 从 A->C
5 将 1 从 B->A
6 将 2 从 B-> C
7 将 1 从 A->C

看不出的朋友 也可以自己写出有4个盘子时的 情况。

从上我们可以看出 要将N个盘子从A->C 就是将 上面的 N-1个盘子 从 A->B 再将第N个 盘子从 A->C 最后再将上面的 N-1个盘子 从 B->C

但是问题是如何将 上面的 N-1 个 盘子从A->B
问题又变为 先将 N-2 个盘子从A->C 再将第 N-1 个盘子从 A->B
最后将 N-2个盘子从C->B.

将 N-2 个 盘子从 A->C 的 情况 与N 相同

由此 我们可以看出 这实际上就是 一个递归调用 当N=1时 就移动盘子 当N/=1时
就用n-1 继续 递归 但此时的 A,B,C三个点需要 变动

先给出 解决该问题的C 源程序


#include "stdafx.h"

void haoni(int ,char, char,char);
void moveto(int ,char,char);


int main(int argc, char* argv[])
{
    haoni(4,'a','b','c');

    return 0;
}

void haoni (int n,char fr,char to,char by)
{
    if(n<=0) return;
    if(n==1)
    {
        moveto (n,fr,to);
        return;
    }
    haoni(n-1,fr,by,to);
    moveto(n,fr,to);
    haoni(n-1,by,to,fr);
}

void moveto (int n,char fr,char to)
{
    printf("\n move %d from %c to %c",n,fr,to);
}

下来 我们分析一下该程序 首先该程序定义了 有 4 个盘子 你也可以自己修改一下

函数 moveto (int n,char fr,char to) 就是把点从 FR->TO 

void haoni (int n,char fr,char to,char by)   核心函数 实现递归调用
{
    if(n<=0) return;
    if(n==1)
    {
        moveto (n,fr,to);
        return;
    }
    haoni(n-1,fr,by,to);     将N-1 个 点从 原点移动到 中间点
    moveto(n,fr,to);           将 第 N个点 从 原点移动到 目标点
    haoni(n-1,by,to,fr);     将 N-1 个点从中间点 移动到目标点
}

这里有 两个 haoni (*,*,*,*) 函数 我们 先看第一个 当 N-1 /=1 是 就反复地 递归调用 自身 每调用一次 都会将 
haoni(n-1,fr,by,to);     
    moveto(n,fr,to);           
    haoni(n-1,by,to,fr);   
全部执行一次
已完成 将N-1 个 点从 原点移动到 中间点

但此时的 A,B,C 三个点需要变动



先带领大家看一下 递归调用的 过程

当 N=3时 调用
void haoni (int n,char fr,char to,char by)
{
    if(n<=0) return;                 再调用 haoni(2,fr,by,to)->再调用haoni(1,fr,by,to)
    if(n==1)                                执行 MOVE(1,FR,TO)->执行MOVE(2,FR,TO)->
    {                                                ->执行 haoni(2,by,to,fr)->.........
        moveto (n,fr,to);
        return;
    }
    haoni(n-1,fr,by,to);
    moveto(n,fr,to);
    haoni(n-1,by,to,fr);
}
   

posted @ 2013-05-11 16:25  一桶白开水  阅读(620)  评论(0编辑  收藏  举报