本文利用杨辉三角来具体说明一个递归的实现,实现的条件,如果理解不对的地方还请指教。
一、杨辉三角说明
杨辉三角是二项式系数在三角形中的一种集合排列。下面引用wiki上的动态图来展示一下。
相信大家看了这张图应该就能明白杨辉三角了吧。下面在代码中讲解递归。、
二、代码讲解
#include<iostream> using namespace std; #define max 10 /*下面定义的这个数组本来是要递归一遍直接记录在数组里面的,而不用每求一个再去递归,但是这道题不大使用,因为在if条件里面有一个return, 如果改的话,就直接计算了,可以不用递归了,所以这里算是强行用一波递归吧嘿嘿嘿*/ int print[max][max] = { 0 }; int digui(int row, int col) { if (col == 0 || row == col) { print[row][col] = 1; return 1; } else { return digui(row - 1, col - 1) + digui(row - 1, col);//这个的值就是前面的两个数相加得来 } } void main() { for (int _row = 0; _row < max; _row++) { for (int _col = 0; _col <= _row; _col++) { printf("%5d", digui(_row, _col)); } printf(" "); } }
首先,如果做的听的递归的题目多了之后,就会发现,递归要满足两个条件:
一是,要有使递归进行下去的变量,在这里就是row和col(行和列);
二是,要有终止递归的条件,在这里就是当row和col相等或者col==1的时候。
递归在经典的问题中用到很多,下面写几个问题的伪程序:
斐波那契数列
13世纪意大利数学家斐波那契的《算盘书》中记载了典型的兔子产仔问题,其大意如下:
如果一对一个月大的兔子以后每一个月都可以生一对小兔子,而一对新生的兔子出生两个月才可以生出小兔子。也就是,1月份出生,3月份开始产仔。那么假定一年内没有产生兔子死亡事件,那么1年之后共有多少对兔子呢?
int Febonaci(int n) { int t1, t2; if (n > 0) { if (n == 1 || n == 2) return 1; else { t1 = Febonaci(n-1); t2 = Febonaci(n-2); return t1 + t2;//规律是第n个月的兔子数等于前一个月和前两个月的兔子数之和; } } else { return 0; } }
汉诺塔
题意:把a上的num个轮盘通过b移动到c上,这num个罗盘大小均不相同,规则是:大罗盘必须在小轮盘上面。
/*这里的num是罗盘的数量,a是罗盘最初在的杆,b是借用实现转移的杆,c是罗盘最终要移动到的杆*/ hanota(num,a, b, c) { if (num == 1) move(1,a, c); else { hanota(num - 1, a, c, b);//把num-1个罗盘移动到b上 move(num, a, c);//把最大的罗盘移动到c上 hanota(num - 1, b, a, c);//把num-1个罗盘移动到c上
} }
三、最后
最后说一下,递归的实现过程吧,我简单说一下,然后给出一个详细说明的链接。
首先应该知道函数时保存在栈中的,当调用函数调用一个被调用函数的时候,就将这个被调用函数压入栈中,并且保存这个函数的“状态“(包括实参等)最后入栈的是调用函数的返回地址,当这个函数执行的时候,调用函数的自变量又被压入栈中。当前面的被调用函数有调用函数的时候,就会继续压栈。所以递归不能无限执行,会溢出。当这个函数执行完的时候,就会被弹出栈,接着执行下一个函数,这里的如何找到下一个函数,是通过一个地址指针。