概念
学习使用递归的前提: 函数理解深入(带参的函数,有返回值的函数,函数的嵌套(就是“自身调用自身”)) 操作时,试验无限递归 递归的终止条件 “回溯时还原现场”保证执行前后程序面对问题的状态是相同的。
递归是程序遍历状态空间的基本方式。
以“原问题”为起点,尝试寻找把状态空间缩小到已知的“问题边界”的路线。
再通过该路线反向回溯的遍历方式,就是递归。
程序在每个步骤应该面对相同种类的问题,这些问题都是原问题的一个子问题,可能仅在规模或者某些限制条件上有所区别,并且能够使用“求解原问题的程序”进行求解。程序在执行变换操作执行三个操作:
- 缩小问题状态空间的规模。程序尝试寻找在 “原问题” 与 “问题边界” 之间的变换路线,并向正在探索的路线上迈进一步。
- 尝试求解规模缩小以后的问题,可能成功,可能失败。
- 如果成功,即找到了规模缩小后的问题的答案,那么将答案扩展到当前问题。如果失败,那么重新回到当前问题,程序可能会继续寻找当前问题的其他变换路线,直到最终确定当前问题无法求解。
在使用枚举算法蛮力搜索问题的整个“状态空间”时,经常需要递归。
枚举算法,就是遍历一遍,逐个举例。
初级的枚举很简单,就是for循环的应用,高级的就很难了,复杂在题目理解和遍历的操作方式
Thinking recursively is natural, but need good amount of training.

void TriangleRev(int x) {if (x <= 0) return;for (int i = 1; i <= x; i++)cout << "*";cout << endl;TriangleRev(x - 1);}/*Call TriangleRev(7)TriangleRev(7) <-- prints 7 stars & new lineTriangleRev(6) <-- prints 6 stars & new lineTriangleRev(5) <-- prints 5 stars & new lineTriangleRev(4) <-- prints 4 stars & new lineTriangleRev(3) <-- prints 3 stars & new lineTriangleRev(2) <-- prints 2 stars & new lineTriangleRev(1) <-- prints 1 star & new lineTriangleRev(0) <-- base caseTriangleRev(1)TriangleRev(2)TriangleRev(3)TriangleRev(4)TriangleRev(5)TriangleRev(6)TriangleRev(7)The output will be:*****************************/

void Triangle(int x) {if (x <= 0) return;Triangle(x - 1);for (int i = 1; i <= x; i++)cout << "*";cout << endl;}/*Call Triangle(7)Triangle(7)Triangle(6)Triangle(5)Triangle(4)Triangle(3)Triangle(2)Triangle(1)Triangle(0) <-- base caseTriangle(1) <-- prints 1 star & new lineTriangle(2) <-- prints 2 stars & new lineTriangle(3) <-- prints 3 stars & new lineTriangle(4) <-- prints 4 stars & new lineTriangle(5) <-- prints 5 stars & new lineTriangle(6) <-- prints 6 stars & new lineTriangle(7) <-- prints 7 stars & new lineThe output will be:*****************************/
How to trace recursion
// Factorial(n) = n * Factorial(n-1).// Factorial(0) = Factorial(1) = 1int Fact(int n){if(n <= 1)return 1;return n * Fact(n-1);}/*Fact(4)4* Fact(3)3* Fact(2)2* Fact(1)2* 1 <-- 23* 2 <-- 64* 6 <-- 24*/
void printNumber(int n) // for n > 0{ // 1234567if(n){printNumber(n/10); // 214/10 = 21cout<<n%10; // 214%10 = 4}}// E.g. 7 = 111 214 = 11010110// If number%2 get for us last bit in binray representation// If we could print last bit, we could printvoid printNumberBits(int n) // for n > 0{if(n){printNumberBits(n/2); // 214/2 = 1101011 last bit removedcout<<n%2; // 214%2 = 0}}
入门例题
爬楼梯
// 理解推导公式后,利用递归实现
菲波那契数列
// 理解推导公式后,利用递归实现
Pell数列
// 需要使用记忆化
