您的位置:首页 > 其它

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

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

首先我们假设三根柱子分别是 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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: