文章

关于Recursive的一些感悟与心得

最近闲暇时光一直在研究一些千奇百怪的东西。看到了很多怪东西,再结合从大一就一直让我感到好奇的递归,似乎恍惚间有了点东西。

What is Recursive? Recursion?

在数学意义上的Recursive包含了递推回归的过程。

而在程序执行的过程中,把大的复杂问题分解成更小更简单的问题,逐级分解下去,直到问题的规模小到可以解决问题,然后再逐级向上回溯解决最初的问题。

在编程中,简单来讲,便是自己调用自己。这与迭代是一样的效果。

递归是由于f(n)扩展到f(1),再由f(1)逐渐算到f(n).

迭代则是直接向下运算,从f(1)到f(n).

Induction and Recursion

似乎这两个有某种联系。

Induction拥有Base Case,以及函数公式本身,通过这些来进行进一步运算来验证公式本身的对与错。

让我们把其证明部分的功能砍掉,似乎就明朗许多。

以下用伪代码与文字,通过斐波那契数列来演示。

• F(0) = 0.

• F(1) = 1.

• For n ≥ 2, F(n) = F(n−1) +F(n−2).

而0与1则是Base Case,在递归里我的理解是防止递归本身无限调用自己,是结束运算的标志

以下是伪代码

1
2
3
4
function F(n)
if n=0 then return 0
if n=1 then return 1
else return F(n-1) + F(n-2)

因此递归完全可以运用Induction的东西来执行。只要寻找Base Case,便可以编写代码。

some examples

比如咱们最常见的查找,既然可以用迭代写,那么递归也没问题。

首先确定Base Case,也就是能阻止无限循环的工具。

在下面的例子里明显是当index==0时存在。

确定后再回溯到Base Case,通过这一过程来完成运算。

1
2
3
4
5
6
7
8
9
10
11
12
13
private T getREcursivehelper(IntNode p,int index){
        if(index==0){
            return p.item;
        }
        return getREcursivehelper(p.next,index-1);
   }
   public T getRecursive(int index){
        if(index>=size){
            return null;
        }
        IntNode p=sentinel;
        return getREcursivehelper(p.next,index);
   }

一些实际的问题也可以用递归解决,比如汉诺塔问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

void Towers(int n,char a,char b,char c){
	if(n==1){
		cout<<"Move disk "<<n<<" from"<<a<<" to "<<c<<endl;
	}
	else{
		Towers(n-1,a,c,b);
		cout<<"Move disk "<<n<<" from"<<a<<" to "<<c<<endl;
		Towers(n-1,b,a,c);
	}
}
int main(int argc, char *argv[]) {
	int n;
	cin>>n;
	Towers(n,'A','B','C');
	cout<< endl;
	
	
}
本文由作者按照 CC BY 4.0 进行授权