现在的位置: 首页 > 综合 > 正文

浅析汉诺塔递归过程

2013年06月26日 ⁄ 综合 ⁄ 共 2775字 ⁄ 字号 评论关闭

           这两天一直在看汉诺塔的递归过程,花了点时间把这个程序仔细分析了几遍,在执行过程的分析中遇到了些问题,上网查了查,也没有找到比较满意的答案,所以就硬着头皮自己解决了,我想我遇到的问题也许很多人也会遇到,于是我就把我对汉诺塔递归过程的分析写了出来,希望对一些人有所帮助,当然,开始前还是声名一下,我这是菜鸟文章,自认为是高手的,还请绕道,谢谢。

废话不多说,上代码:

#include<stdio.h>

void move(char x,char y)

{

     printf("%c-->%c/n",x,y);

}

void hanoi(int n,char one,char two,char three)

{

     if(n==1)

     {

         move(one,three);

     }

     else

     {

          hanoi(n-1,one,three,two);

          move(one,three);

          hanoi(n-1,two,one,three);

     }

}

void main()

{

       int m;

       printf("请输入盘子数:");

       scanf("%d",&m);

       printf("%d个盘子的移动步骤为:/n",m);

       hanoi(m,'A','B','C');

}

 

    可以看出,代码是由三部分组成:move()函数、hanoi()函数和main()函数,其中move()函数是用来输出表示输出方式的字符串的,hanoi()函数是用来控制盘子移动的(要明白,这里的控制盘子移动不是真的在移动盘子,只是控制盘子输出方案的),main()函数就不多说了。

    

问题主要集中在hanoi()中,下面我来具体分析:

我以n==3为例

 

1      void hanoi(int n,char one,char two,char three)

{

            2            if(n==1)

                          {

            3                     move(one,three);

                          }

            4            else

                          {

            5                    hanoi(n-1,one,three,two);

            6                    move(one,three);

            7                    hanoi(n-1,two,one,three);

                          }

      }

 

 在main()函数中,hanoi(n,’A’,’B’,’C’)表示的是n个盘子从A柱经过B柱移到C柱,这里我们只分析n==3的情况。记住,这个hanoi里的参数是实参,实参传递到第1行中的形参,此时,one=Atwo=Bthree=C。然后走第2行,n不等于1,所以执行else中语句,到第5行,又有一个函数调用,这时n变成2,第5行为hanoi(2,’A’,’C’,’B’),这里一定要理解,然后这一个hanoi里的参数成为实参,接着就是所谓的递归,调用自身,所以程序回到第1行,此时,one=Atwo=Cthree=B,然后和刚才一样,n不等于1,走第5行,这时第5行为hanoi(1,’A’,’B’,’C’),很刚才一样,这里面的参数是实参,就又回到第1行,此时,one=Atwo=Bthree=C。接下来走第2行是发现n==1,所以执行move(one,three),也就是会输出AàC,这也就是程序输出的第一个步骤。

这之后就是我当初没有理解的地方了,第3行执行完后再执行哪儿呢?注意了,当n==1后,第3行其实相当于第5hanoi函数的函数体,第3行执行完后就相当于第5行执行完毕,接下来就开始执行第6行,也许有人会说了,执行了if语句里的程序怎么又执行else里的呢?在这里,就需要大家记住这是个递归过程,这里确实开始有点难理解,所以需要大家好好的想想了。

好,接着刚才的,执行第6行,move(one,three),这时,又有个问题出现了,这里move中的onethree分别是什么呢?也许有人会说,刚才第5行的A,B,C传给第1行后one就是A了,three就是C了呀,在这里,请注意了,第5行的onetwothree和第1行的onetwothree是占用的不同的存储空间,只是名字一样罢了,这个调用只是传递值,而不会传递地址,所以第6move中的one=A,three=B,所以程序的第二个步骤终于出现了:AàB

OK,继续,搞懂了上面的值传递后,接下来第7行中的参数就应该知道是什么了吧,我还是写出来吧,hanoi(1,’C’,’A’,’B’)。同样,这是实参,调用到第1行,就是one=C,two=A,three=B,然后就是第3行,程序的第三个步骤就出来了:CàB

到这里,又到了不好理解的地方了,以上的步骤主要是完成了当n==1时的情况,而hanoi(n=1)中包含三个部分:一是hanoi(n=2,one,three,two),二是move(one,three),三是hanoi(2,two,one,three);而hanoi(n=2,one,three,two)中又包含{ hanoi(1,one,three,two)move(one,three)hanoi(1,two,one,three)},所以,以上的步骤也就是说完成了大括号中的内容,接下来就要开始执行和它并列的move(one,three),这里一定要好好琢磨琢磨,理清这里面的层次,搞懂为什么要执行move(one,three)。好了,搞懂之后,执行move(one,three),输出程序的第四个步骤:AàC(注意要搞清楚这里的onethree得到的值是从hanoi(n=3,’A’,’B’,’C’)中来的,因为这是和hanoi(n=2,one,three,two)并列的)

因为move中没有包含其他的语句,所以接下来就开始执行最后一个并列的hanoi函数,也就是hanoi(2,two,one,three)(此时,one=Atwo=Bthree=C)。这个就和先前最开始的是一模一样的,因为n不等于1,所以到第1hanoi(2,B,A,C),往下到第5行:hanoi(n=1,B,C,A),在到第3行(接下来我就不详细写了),第五个步骤出来:BàA

抱歉!评论已关闭.