<C语言>递归思维及其实现-----汉诺塔问题

<<<<<<<递归思维及其实现>>>>>>>>>>
作者:wsg

时间:2017年8月17日

1、概念:
·一个过程或一个函数,在其定义或者说明中有直接或间接地调用自身的一种思想方法。

2、递归条件:
·子问题和原始问题是相同的事情;
·不能无限制地调用,必须有个出口(边界条件)。

3、如何设计递归算法:
·确定递归公式;
·确定边界条件。

4、递归一般用来解决:
·数据的递归定义;
·递归算法的实现;
·数据结构形式按递归定义(比如二叉树)。

5、递归算法相对于常用的算法(如for循环),运行效率低。若操作不当,很容易造成栈溢出等错误。所以在设计算法的时候,尽量避免使用递归。除非没有更好的算法,或者只能使用递归的时候才使用。

6、经典实例:汉诺塔问题。(后面例3有代码)

7、注意:
·一定要有一个边界条件;
·不要在递归函数里面申请大块内存(malloc)


递归模板:

递归:
1.确定参数
2.确定参数的函数
3.确定简单情况下的函数
4.确定复杂情况下的函数

==============================
模板:
int f(参数)
{
if (简单情况条件)
return 简单情况下函数
else
return 复杂情况下函数
}

汉诺塔:
参数n:盘子个数
设f(n):n个盘子总共需要移动的步数

简单情况下的函数
f(n) = 1   n = 1;
复杂情况下的函数
f(n) = 2f(n-1)+1;  //(n > 1)

===============================

例1:输出1-100

/********
===使用for循环做简单很多===
#include <stdio.h>
int main(void)
{
	int i;
	for(i=1; i<=100; i++)
	{
		printf("%d\n", i);
	}
	return 0;
}
*********/

//使用递归算法
#include <stdio.h>

void func(int n);

int main(void)
{
	int a = 100;
	func(a);
}

void func(int n)
{
	if(n>1) //递归的边界条件
	{
		func(n-1); //函数调用自身,递归
	}
	printf("%d\n", n);
}

/***可以这样来理解:
void func(int n)
{
	if(n>1)
	{
		if((n-1)>1) //递归的边界条件
		{
			func((n-1)-1); 
			//一层一层进去,再从最里面出来,故打印出来的结果就是1-100
		}
		printf("%d\n", n);
	}
	printf("%d\n", n);
}
*****/


例2:输入一个整数,求1^2+2^2+3^2+……+n^2

#include <stdio.h>

int recursion(int n); //声明

int main(void)
{
	int a, sum;
	printf("请输入一个整数:\n");
	scanf("%d", &a);
	
	sum = recursion(a);
	printf("结果为:%d\n", sum);
}

int recursion(int n) //递归函数的定义
{
	if(n>1)
	{
		return n*n+recursion(n-1); 
		//recursion(n-1)将一层一层递归执行return n*n+recursion(n-1)下去,直到n>1不成立。
	}
}	


例:3:<汉诺塔>有三根柱子A、B、C,有n个大小不一的圆盘,原始状态,所有圆盘都在A柱上(上面圆盘必须必下面圆盘小),现在要求,将所有圆盘移动到C上,一次只能移动一个,并且必须放在某一根之子上。找出移动次数最小的方案。

#include <stdio.h>

void func(int n, char from, char buf, char to);

int main(void)
{
	int n; 
	char col[3] = {'A','B','C'};//定义三根柱子
	
	printf("请输入圆盘个数:\n");
	scanf("%d", &n); //输入有多少个盘
	
	printf("最简移动方案:\n");
	
	func(n,'A', 'B', 'C');
	
	return 0;
}

//用n个盘,原始盘全在from上,要移动到to上,中间工具用buf作过渡
void func(int n, char from, char buf, char to)
{
	if(n == 1)
	{
		printf("%c--->%c\n", from, to);
	}
	
	else
	{
		func(n-1, from, to, buf); //A--->B柱
		printf("%c--->%c\n", from, to);
		
		func(n-1, buf, from, to); //B--->C柱
	}	
}

例3:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值