一、 什么是递归
程序调用自身的编程技巧称为递归( recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
注意:
递归就是在过程或函数里调用自身;
举个例子来说:
从前有座山,山上有座庙,庙里有一个老和尚和一个小和尚,老和尚正在给小和尚讲故事。
讲的是什么故事呢?他说,从前有座山,山上……
我们发现这个故事是一直重复讲述的,我们之前是通过循环结构来实现重复执行某些代码的,那么如何通过递归代码来实现这个故事呢? 我们来看下面这段代码:
#include "windows.h" void tell_story( ) { printf("从前有座山,山上有座庙,庙里有一个老和尚和一个小和尚 "); printf("老和尚正在给小和尚讲故事。讲的是什么故事呢?他说: "); Sleep(1000); tell_story ( ); // tell_story 函数的递归调用 } void main() { tell_story( ); }
我们发现, 通过递归调用,也就是函数调用自身这一方法来实现讲故事这以代码,代码是可以执行的,但是却形成了一个死循环.之前我们学习循环的时候,我们对循环是有控制条件的,那么在我们使用递归的时候是否应该和使用循环一样,应该有个控制递归的条件呢?这个控制条件应该是什么呢?
注意:
递归就是在过程或函数里调用自身;
在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
汉诺塔游戏代码
/* 汉诺塔游戏解决过程*/ #include "stdio.h" //整型全局变量,预置1,步数 int step=1; //void表示该函数没有返回值,只是执行了一些操作 void move(int m,char p,char q,char r) { if(m==1) //如果m为1,则为直接可解结点 { //输出移盘信息 printf("第%d步 move 1# from %c to %c ",step,p,r); //步数加1,准备进行下一步 step++; } else { move(m-1,p,r,q);//递归调用move(m-1) //直接可解结点,输出移盘信息 printf("第%d步 move %d# from %c to %c ",step,m,p,r); //步数加1 step++; //递归调用 move(m-1,q,p,r); } } void main() { int n; printf("请输入盘数:"); scanf("%d",&n); printf("在3根柱子上移%d只盘的步骤为 ",n); move(n,'A','B','C'); }
斐波那契数列代码
/* Note:Your choice is C IDE */ #include "stdio.h" int fun(int n) { if(n==1||n==2) return 1; else return fun(n-1)+fun(n-2); } void main() { int n; printf("请输入月数:"); scanf("%d",&n); printf("%d月有%d对兔子 ",n,fun(n)); }
递归 求阶乘
#include "stdio.h" int fun(int n) { if(n==1) return n; else return n*fun(n-1); } void main() { int n; printf("请输入一个数:"); scanf("%d",&n); printf("%d!=%d ",n,fun(n)); }