算法思想篇(3)————递归算法
在计算机编程应用中,递归算法对解决大多数问题是十分有效的,它能够使算法的描述变得简洁而且易于理解。递归算法有如下3个特点。
(1)递归过程一般通过函数或子过程来实现。
(2)递归算法在函数或子过程的内部,直接或者间接地调用自己的算法。
(3)递归算法实际上是把问题转化为规模缩小了的同类问题的子问题,然后再递归调用函数或过程来表示问题的解。
在使用递归算法时,读者应该注意如下4点。
(1)递归是在过程或函数中调用自身的过程。
(2)在使用递归策略时,必须有一个明确的递归结束条件,这称为递归出口。
(3)递归算法通常显得很简洁,但是运行效率较低,所以一般不提倡用递归算法设计程序。
(4)在递归调用过程中,系统用栈来存储每一层的返回点和局部量。如果递归次数过多,则容易造成栈溢出,所以一般不提倡用递归算法设计程序。
下面两个例子说明递归算法的思想:
(1)汉诺塔问题:
代码如下:
//start from the very beginning,and to create greatness
//@author: Chuangwei Lin
//@E-mail:979951191@qq.com
//@brief: 汉诺塔
#include <stdio.h>
/******************************************************
函数名:move(int n,char x,char y,char z)
参数:个数,柱子编号
功能:移动函数
*******************************************************/
void move(int n,char x,char y,char z)
{
if (n==1)
printf("%c-->%c\n",x,z);//若只有1个,则直接移动,结束条件
else
{
move(n-1,x,z,y);//借助第三根移动到第二根
printf("%c-->%c\n",x,z);//自己移动最后一个盘
move(n-1,y,x,z);//借助第1根移动到第三根
}
}
void main()
{
int number;
printf("输入盘子个数: ");
scanf("%d",&number);
printf("移动%2d 个盘子的步骤如下:\n",number);
move(number,'a','b','c');//开始移动
}
运行结果:
(2)阶乘问题:
代码如下:
//start from the very beginning,and to create greatness
//@author: Chuangwei Lin
//@E-mail:979951191@qq.com
//@brief: 阶乘
#include <stdio.h>
int fact(int n);//计算函数
int main()
{
int i;
printf("输入要计算阶乘的一个整数:");
scanf("%d",&i);
printf("%d的阶乘结果为:%d\n",i,fact(i)); //递归调用
return 0;
}
int fact(int n)//递归子函数
{
if(n<=1)//0!=1,1!=1
return 1;
else
return n*fact(n-1);
}
运行结果: