• 栈与递归(Hanoi塔问题)


      今天上午上课时,再看了下Hanoi塔的问题,其中对递归的分析,让自己对递归调用有了更深一步地理解,把书上的代码实现一下,然后分析其递归工作栈的状态,理解了以后,会让自己受益颇多。学习,不能只看着别人是怎么写的,自己就照着写,这是非常不对的,你要分析别人为什么这样写,你要懂得的是思路,而不仅仅是答案。

     1 #include<stdio.h>
     2 static int c;
     3 void hanoi(int n,char x,char y,char z)
     4 {
     5     if(n==1)//将编号为1的圆盘从x移到z
     6         printf("%d step: Move disk %d from %c to %c\n",++c,n,x,z);
     7     else
     8     {
     9         hanoi(n-1,x,z,y);//将x上编号为1至n-1的圆盘移到y,z作辅助塔
    10         printf("%d step: Move disk %d from %c to %c\n",++c,n,x,z);
    11          //将编号为n的圆盘从x移到z
    12         hanoi(n-1,y,x,z);//将y上编号为1至n-1的圆盘移到z,x做辅助塔
    13     }    
    14 }
    15 int main()
    16 {
    17     int n;
    18     printf("请输入hanoi塔的阶数:\n");
    19     scanf("%d",&n);
    20     hanoi(n,'A','B','C');    
    21 }

    运行结果:

    分析:

       假设n=3,递归第一层的状态为(返址:0,3,A,B,C)执行到第9行语句时,递归调用第二层(返址:6,2,A,C,B) 此时栈的状态时在第一层之上,继续递归调用又回到第9行语句,递归调用第三层(返址:6,1,A,B,C)此时栈的状态时在第二层之上,继续递归调用,这时n=1,所以会有第一步的输出,A->C.输出后,跳到第14行语句也就意味着递归的第三层函数调用结束,返回到递归调用的第二层(返址:6,2,A,C,B)继续向下执行到第10行代码,这是第二步输出,A->B.

    然后执行到第12行代码,这是又遇到递归函数,前面还有两层递归调用,所以这是递归调用第三层(返址:8,1,c,a,b),执行递归调用,此时n=1,所以第三步输出,C->B,执行完后跳到14行代码,以为着第二层函数调用结束,返回到第一层(返址:0,3,A,B,C),第一层的递归调用执行第10行代码,就会用第四步输出,A->C,继续执行到第12行代码,又遇到递归调用,此时状态为递归调用第二层(返址:8,2,B,A,C),继续执行,会到第9行代码此时又遇到递归调用,递归调用第三层(6,1,B,C,A),继续执行此递归调用,到第5行代码,此时n=1所以输出第五步:B->A.执行完后到第14行代码,这是意味着第三层递归调用结束,回到第二层递归调用,接着执行第10行代码,这是第六步输出:B->C. 执行完后到12行代码,又遇到递归调用(返址:8,1,A,B,C),递归调用执行到第5行代码,满足条件,输出第七步:A->C。回到第二层递归调用,第二层递归调用又执行到第14行代码,这意味递归调用结束,返回主函数。

    找下规律,从运行的效果图可以看出:

    根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;看第2块,从A->B,B->C

    若n为奇数,按顺时针方向依次摆放 A C B。看第一块,A->C,C->B,B->A,A->C.第3块:A->C
    呵呵,百度的时候,看到还有这样的智力游戏,这下我碰到了应该会玩了哈。。。

    总结:自己分析得不怎么好,当自己去想,自己去做时,会发现书上写得有多好,自己写的水平有多差了。hanoi塔问题,找到简单的办法解决看似复杂的问题。不过递归调用也不简单,虽然只有那么几行代码,可是分析起来是会死掉一些脑细胞的。。。嘻嘻。。。

  • 相关阅读:
    Redis实战——redis主从备份和哨兵模式实践
    Shiro的Subject和Sessoin的创建
    Shiro配置cookie以及共享Session和Session失效问题
    Shiro的校验Session是否过期处理的过程
    Maven父级pom.xml配置文件
    我的Linux之路——虚拟机linux与主机之间的文件传送
    Redis实战——安装问题汇总
    我的Linux之路——实现虚拟机VMware上linux与windows互相复制与粘贴
    Redis实战——phpredis扩展安装
    推荐一个面向对象的javascript框架mootools
  • 原文地址:https://www.cnblogs.com/wj204/p/3110819.html
Copyright © 2020-2023  润新知