3.4、递归定义及其应用(汉诺塔)

一、定义
    一个函数自己直接或间接的调用自己;
    PS:通常,当一个函数的运行期间调用另一个函数时,在运行被调用函数之前,系统需要先完成3件事:
    (1)将所有的实在参数、返回地址等信息传递给被调用函数保存;
    (2)为被调用函数的局部变量分配存储区;
    (3)将控制转移到被调函数的入口;
    而从被调用函数返回调用函数前,系统也应完成3件工作:
    (1)保存被调函数的计算结果;
    (2)释放被调函数的数据区;
    (3)依照被调函数保存的返回地址将控制转移到调用函数。
    当有多个函数构成嵌套调用时,按照“后调用先返回”的原则,上述函数之间的信息传递和控制必须通过“栈”来实现,即系统将整个程序运行时所需要的数据空间安排在一个栈中,每当调用一个函数时,就为它在栈顶分配一个存储区,每当从一个函数退出时,就释放他的存储区,则当前正运行的函数的数据区必在栈顶。

 

//函数的互相调用略,,函数自己调用自己具体演示如下(当然,在学C语言的时候,算阶乘和斐波拉契数列时,表示这种函数调用);

# include <stdio.h>

void f(int n)
{
	if(n==1)
		printf("瓜洲风流倜傥\n");
	else
		f(n-1);
}

int main(void)
{
	f(3);

	return 0;
}

二、举例

1、求阶乘

#include <stdio.h>

//假定n>=1
long f(long n)
{
	if(1==n)
		return 1;
	else
		return f(n-1)*n;
}

int main(void)
{
	printf("%ld\n", f(6));
	return 0;
}

2、求1+2+3+·····+100;  略

3、汉诺塔

#include <stdio.h>

void hannuota(int n, char A, char B, char C)//参数A代表要移动的柱子,参数B代表要借助的柱子,参数C代表最后要放的柱子
{

/*	如果是1个盘子
		直接将A柱子上的盘子从A移到C
	否则
		先将A柱子上的N-1个盘子借助C移到B;
		再将A柱子上的盘子从A移到C;
		最后将B柱子上的N-1个盘子借助A移到C;
*/
	if(1==n)
	{
		printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);
	}
	else
	{
		hannuota(n-1, A, C, B);
		printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);
		hannuota(n-1, B, A, C);
	}
}

int main(void)
{
	char ch1='A';
	char ch2='B';
	char ch3='C';
	int n;

	printf("请输入要移动盘子的个数:");
	scanf("%d", &n);
	hannuota(n, 'A', 'B', 'C');

	return 0;
	
}

4、走迷宫

将地图分成无数个小格子,将每个方向的位置放在栈中,走通就是进栈,后退就是出栈。(具体算法很复杂)

 

三、递归的应用
    树和森林就是用递归的方式定义的;
    树和图的很多算法都是以递归实现的;
    很多数学公式就是以递归的方式定义的(斐波拉契数列);
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/GUA8122HOU/article/details/88377396
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞