C语言函数递归调用汉诺塔问题

#include <stdio.h>
int main()
{
void hanoi(int n,char one ,char two,charthree);
int m;
printf("input the number of diskes:\n");
scanf("%d",&m);
printf("The step to move %ddiskes:\n",m);
hanoi(m,'A','B','C');
}
void hanoi(int n,char one ,char two,charthree)
{
void move(char x,char y);
if(n==1)
move(one,three);
else
{
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
}
}
void move(char x,char y)
{
printf("%c->%c\n",x,y);
}
/////////////////////////////////////////////////////////////////////分割线///////////////////////////////////
我现在理解函数可能陷入一个误区了,就拿这题来说。hanoi函数内部没有一条语句是起作用的。什么意思,比如我假定一个新函数add:
Int add(int a,int b)
{
Int c;
c=a+b;
return c;
}
这个函数我通过c=a+b;这条语句很明显就知道了这是执行相加运算的函数。但是反观这道题,hanoi直接就是个空函数,里面一条起作用的语句都没有,怎么就能运算出结果,这点让我非常的头疼。而且在hanoi函数中又调用了hanoi函数,我知道这是递归。但是这函数里面是空的啊。
void hanoi(int n,char one ,char two,charthree);这只是单纯的定义函数变量,没有具体功能。只是说理解的时候可以理解成:将n个盘子从one通过two移动到three。但计算机不会这么理解。它是怎么通过hanoi空函数实现功能的,这点才是我最想,也是最迷糊的地方,希望你能帮我指点迷津

我一步步的给你讲,就会懂啦:

 

首先hanoi函数如果把当中的move函数给去掉,就变成了:

void hanoi(int n, char one , char two, charthree)
{
    if(n == 1)
        printf("%c->%c\n", one, three);
    else
    {
        hanoi(n - 1, one, three, two);
        printf("%c->%c\n", one, three);
        hanoi(n - 1, two, one, three);
    }
}

也就是把move(one,three),变成了printf("%c->%c\n", one, three);。少了一个函数,更加清晰

 

所以这里的hanoi函数就有了执行的内容:printf

 

 

下面以3个盘子为例进行模拟计算机的执行过程:

 

1、hanoi(3,A,B,C),开始了这步,进入第一层函数,计算机在函数中会进行自我的再次调用(第7行代码)

 

2、(第7行):hanoi(2,A,C,B),于是这又是一个新的hanoi函数,这里我把它成为第二层函数

同样执行到第7行,卡住了,再次一次自我的调用

 

3、(进入第三层函数):hanoi(1,A,B,C),这里的第三层n=1,所以在第四行就显示出了"A->C",至此,第三层函数结束,回到调用他的第二层函数

 

4、在第二层当中,继续第8行的内容,所以显示出"A->B",继续运行,到第9行,开始了有一次自我调用

 

5、把她称为贰号第三层函数吧。。。hanoi(1,B,A,C),和第3步类似,这一层函数显示出了"B->C",然后结束函数,返回调用它的第二层函数

 

6、第二层函数执行完毕,返回调用它的第一层函数

 

7、第一层函数中执行到第8行,显示出"A->C",然后执行第9行:hanoi(2,B,A,C)

............

 

 

如果看到了这里理清楚了关系就会懂啦,接下来还有一半,如果都写下来就太复杂了-。-

你所说的空函数是指没有返回值,但是这里利用的是电脑调用函数的那种关系来解决的问题,比如上面的3步,会自动返回到第二层函数并继续

还可以这样理解汉诺塔,汉诺塔其实是将复杂的问题简单化,

先不管他有多少个盘子从A到C,我只把它视作3步

 

就像上面那样找个例子,反复的按照代码模拟计算机运行,过个五次六次,就会懂啦

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-08-07

这个程序是一个递归程序,并不是直接出结果的,我简单解释下好了

首先你要明白函数调用过程,比如:

……
fun();
a++;
……

在这个例子中,fun结束了会执行a++这种语句,这点没问题吧。递归函数会重复调用同名的函数,但是不代表退出了一个同名函数就直接退出了整个函数,而是一层层的返回的。

以你的程序为例:(同一个缩进表示同一层,每缩进一次就进入下一层调用)

//取n=3
hanoi(3,'A','B','C');//main中调用
    hanoi(2,'A','C','B');//n=3,执行else
        hanoi(1,'A','B','C');//n=2,执行else
            move('A','C');//n=1,执行if,完毕后return到调用出执行下一句
        move('A','B');//else中第二句
        hanoi(1,'C','A','B');//else中第三句
            move('C','B');//返回调用处,但hanoi(2,'A','C','B')也执行完毕,继续返回
    move('A','C');
    hanoi(2,'B','A','C');
        hanoi(1,'B','C','A');
            move('B','A');
        move('B','C');
        hanoi(1,'A','B','C');
            move('A','C');
        //返回至hanoi(1,'A','B','C');
    //返回至hanoi(2,'B','A','C'); 
//返回至main中调用hanoi(3,'A','B','C');

递归虽然有点抽象,但还是按照函数调用的规则的,都是调用,结束返回到调用处。刚开始都是展开过程,直到遇到了递归结束条件,才结束递归调用的过程

你这里的递归函数并不是你说的空函数,你仔细看下在这个函数执行过程中,肯定有某些语句是起作用的,你这里就是move起作用了,你仔细理解下

第2个回答  2017-08-15

#include<stdio.h>

void move(int n,char a,char b,char c)

{

if(n==1)

printf("\t%c->%c\n",a,c);    //当n只有1个的时候直接从a移动到c

else

{

move(n-1,a,c,b);            //第n-1个要从a通过c移动到b

printf("\t%c->%c\n",a,c);

move(n-1,b,a,c);            //n-1个移动过来之后b变开始盘,b通过a移动到c,这边很难理解

}

}

main()

{

int n;

printf("请输入要移动的块数:");

scanf("%d",&n);

move(n,'a','b','c');

}

第3个回答  2015-11-18
先调用一次hanoi(m,'A','B','C'),其中参数m是你输入的值.
如果你输入的m为1,则直接调用move(one,three),然后直接输入 A-->C换行
如果你输入的m不为1,假设为2,则执行过程如下
执行一次hanoi(1,one,three,two),执行 move(one,three),然后直接输出A-->B换行
执行一次move(one,three),然后直接输出 A-->C换行
执行一次hanoi(1,two,one,three),执行move(one,three),然后直接输出B-->C换行
如果你输入的数字>2那就相应的进入到更多层的hanoi()函数中循环
第4个回答  2013-08-07
这个递归根本就不需要运算,如果你非要理解成一定要有运算的话,那他那个输出就算是运算了,只是递归调用的时候是根据上一层递归而改变的,主要还是你要理解这个算法的逻辑过程,而不是纠结于怎么运算,在纸上一步一步演算一下你就会懂得。

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网