汉诺塔游戏的递归解析

递归

递归就是程序自己调用自己的过程。
本身理解递归的思想比较容易,举一个求阶乘的例子:

def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)

测试:

>>> fact(1)
1
>>> fact(5)
120

实际上递归程序不可能一直递归循环下去,需要利用其它条件来结束递归循环。这里求阶乘的例子,就是当n==1时就结束递归循环。
这里以fact(5)为例,看程序是如何进行递归运行的

===> fact(5) 
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

可以看出程序从fact(5)递归到fact(1)结束。从上到下递归至结束,然后从下至上依次计算。

汉诺塔游戏

上面这个递归求阶乘很好理解。但是将递归的思想放到汉诺塔中,就不是那么容易明白了。(关于汉诺塔的文章,其实网上很多了,这里不会很详细解说。)简单说下汉诺塔游戏的规则和玩法:

  1. 有三个柱子: a, b, c;
  2. a 上有数量为N个的圆盘;
  3. 从a柱将数量为N个的圆盘拿到 c 柱上;
  4. 一次只能拿一个圆盘,a,b,c 柱都可以利用;
  5. 无论在哪根柱子上,都是较大的圆盘永远在较小圆盘下面。

为了方便后面的理解,这里先说明几个字母含义:

N:一个标量,在下文中表示,第N个圆盘,N-1,第N-1个圆盘
n: 代表前n个圆盘, n-1 代表前n-1个圆盘;
a,b,c:分别表示三根柱子;
—>: 箭头表示从...移动到...

玩汉诺塔游戏可以分为三步:

  1. 将n-1个圆盘从 a 移到 b上;
  2. 将N圆盘从a 移到 c 上;
  3. 将n-1 个圆盘,从b 移到c 上。

玩汉诺塔就是不断重复那三步,直到n-1=1

递归运行图

要将 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-3个从a移到b,然后将N-2从a移动c,再将n-3从b移到c;
要将n-3个从a移到b,
则先将n-4个从a移到c,然后将N-3从a移动b,再将n-4从c移到b;
......
在递归到最后一层,n- (n-1)=1, 也就是 a 柱第一个圆盘移向 b 还是 c 取决于N是奇数还是偶数。(代几个数测试下就知道了)
注:要将n-k个从一个柱子移到另一个柱子,需要借助第三个空闲柱子

红色部分递归路径,假设其为递归1号路线,在其下面还有其它递归分支(绿色表示)。等红色的从上往下递归到底后,程序从底下,往上开始计算,遇到绿色则开始递归,等绿色递归完后继续计算上一层的。
程序一开始的递归沿着红色一直递归到最后一层(实际圆盘中最上面的那个)不再进行递归,直接开始搬运圆盘。然后运行最后一层的剩余步骤(黑色,红色),最后一层运行完,
等计算完,红色部分递归1号路线
程序运行N(a)->c,
然后开始蓝色部分的递归路径(称其递归2号路线),递归2号路线同1号路线一样也有许多递归支路。

为帮助理解,下面是一个路线图,挺丑的,凑合看。。


运行路线图(T_T)

如果单纯值拿红色递归1号路线(不包括其递归支线),其实其和上面的递归阶乘的例子是一样的。但是汉诺塔这个有了许多递归支线,就感觉复杂了许多。同时也可能因为从a->b, a->c, b->c, a->c,a-b...这三个字母混去混来的,脑袋记不住它们关系了,容易犯浑。但是你像图片那样将递归推导列出来就容易明白了。

代码

# Python
def move(n, a, b, c):   #从a将n个圆盘到c
    if n == 1:
        print(f"{a} --> {c}")
    else:
        move(n-1, a, c, b)  #先将n-1圆盘从a移动到b
        print(f"{a} --> {c}") #然后将a移到c
        move(n-1, b, a, c) #再将n-1圆盘从b移动到c
move(4,'a', 'b', 'c')

#include <stdio.h>  
// C
void move(int, char, char, char);

void move(int n, char x, char y, char z)
{
        if (n == 1)
        {
                printf("%c --> %c\n", x, z);
        }
        else
        {
                move(n-1, x, z, y);
                printf("%c --> %c\n", x, z);
                move(n-1, y, x, z);
        }
}

int main()
{
        int n;
        scanf("%d", &n);
        move(n, 'a', 'b', 'c');
        return 0;
}

参考:

递归函数

原文: 汉诺塔游戏的递归解析

相关文章:

二叉树与汉诺塔

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 8,988评论 0 13
  • 汉诺塔游戏,是个佷益智的游戏,其中也蕴含了一些数学的知识,故事的背景甚至蕴含了一些古人对宇宙的思考。今天我们来聊下...
    家和万事亨阅读 766评论 0 1
  • 前置文章:递归算法:www.jianshu.com/p/703069f3ba3f . 汉诺塔问题是来源于印度传...
    郎小凯阅读 767评论 0 1
  • 原文链接(转载请注明出处)汉诺塔的图解递归算法 起源 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大...
    Dmego阅读 1,546评论 0 0
  • 我的博客:递归之汉诺塔问题 一.起源: 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的...
    taylar_where阅读 921评论 1 3